Does it make sense [C ++ 11: 12.8 / 7]?

[C++11: 12.8/7]: If the class definition does not explicitly declare the copy constructor, one is declared implicitly. If the class definition declares a move constructor or transfers an assignment operator, the implicitly declared copy constructor is defined as deleted; otherwise, it is defined as default (8.4) . The latter case is deprecated if the class has a custom copy assignment operator or a user-declared destructor. So for class definition

 struct X { X(const X&, int); }; 

The copy constructor is implicitly declared. If the constructor declared by the user is later defined as

 X::X(const X& x, int i =0) { /* ... */ } 

then any use of the copy constructor X s is poorly formed due to ambiguity ; no diagnostics required.

It doesn't really matter to me.

How does an example code introduced “in this way” have anything to do with the “last” case in italics?

So far, I understand that:

  • If the class definition does not explicitly declare the copy constructor, but
  • the class definition does not declare a move constructor or a move destination operator, but
  • the class has a user-assigned copy assignment operator or user-declared destructor, then
  • an implicit copy constructor is defined as default ed, and this is deprecated.

It seems strange in itself that standard behavior is - in one breath; condemned. Does this mean that having a class satisfying these three conditions is not recommended?

And what is the sample code? This constructor is not a copy constructor, move constructor, move assignment operator, copy assignment operator, or a user-declared destructor; it's just a user-declared constructor, no? Where is this "ambiguity"?

Can anyone decrypt this passage for me?

+4
source share
3 answers

Does this mean that having a class satisfying these three conditions is deprecated?

Yes; if you have a destination-declaration-statement or user-declared destructor, you must also declare a copy constructor. This basically just means that your class should follow the Rule of Three (or Five or something else that it calls in C ++ 11).

It seems odd in itself that standardized behavior - in one go - is out of date.

The behavior is defined by the standard, because it was behavior in C ++ 03 - changing it would violate outdated code. Just as the standard defines the behavior (for example) of dynamic exception specifications, and also devalues ​​them.

How does an example code introduced “in this way” have anything to do with the “last” case in italics?

This has nothing to do with the “last” case.

This is an illustration of a potential problem caused by the usual behavior defined by a sentence: there will be a conflict between the implicit declaration of the copy constructor and the user-declared constructor with default arguments, so that it can be called as the copy constructor.

Where is this "ambiguity"?

Consider the code:

 X x1; // assume there also a default constructor X x2(x); 

Should x2 initialized with a constructor declared by the user (with the second argument accepting the default value), or with a constructor with an implicit declaration? Both options are equally good to use. This is an ambiguity.

+3
source

Just to answer the second part. Uncertainty is caused by the default parameter int i = 0 , which allows you to call the constructor only with the first argument const X& x , which allows you to use it as a copy constructor, since it is compatible with the signature X(const X& x) (§12.8 / 2 for exact text ) This conflicts with the implicit copy constructor, therefore ambiguity.

+3
source

It seems that the role of the move constructor is being figured out and how it affects the copy constructor. He says that if you declare a move constructor or a move destination operator, there will be no implicit copy constructor. If you define your own copy constructor or copy assignment operator, you can ignore the bit that you placed in the text in bold .

I think the point of the example was to show that for the class:

 struct X { X(const X&, int); }; 

The copy constructor is implicitly defined because there is no custom copy constructor. However, if you specified a default value for the second int argument (as they did), then the call:

 X newX(oldX); 

There may be a call to a user-defined constructor or copy constructor: this is the ambiguity they are talking about.

+2
source

Source: https://habr.com/ru/post/1390810/


All Articles