Is an explicit ctor move eliminating an implicit ctor copy?

I read in the accepted answer here that:

Copy constructor

[a] and copy assignment operator will not be generated for a class that explicitly declares a move or move operator

I notice (g ++ 4.7.2) that if you define a move constructor, it will be used with, for example, push_back() , whereas if you do = delete the copy constructor, you will not get an implicit move mechanism - you get an error message . [... which makes me wonder which one (moving or copying) is actually used if you are not doing anything explicitly ...]

However, this online link does not make the same explicit promises about the copy constructor, which is implicitly defined when defining the movement of the constructor.

So my question is: is the first quote guaranteed by the standard (including "or" )? I would prefer that some classes that needed an explicit destructor fulfill the "rule of five" with only the move constructor and the (delete) move operator, and rely on implicit copy methods that are not defined. If I cannot rely on this, then I will have to explicitly =delete them, but this is a lot of potentially redundant things.

+4
source share
2 answers

So my question is: the first quote guaranteed by the standard (including "or" )?

Yes, your first quote is guaranteed by standard.

Quote from the standard (project n3690):

12.8 Copying and moving class objects [class.copy]

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 user-declared copy destination operator or a user-declared destructor.

+6
source

An interesting continuation - why?

In C ++ 98 there was a Rule of Three :

If you define any of the following, you must define all three:

  • destructor
  • copy constructor

This rule of thumb was created because many people only thought about releasing the resource stored in the destructor and forgot about the consequences that this special behavior had on the copies.

When C ++ 11 appeared around the corner, a number of people claimed that this problem was caused by the default definition provided by the language, and that it would be better to look back so as not to provide them by default. Of course, C provides them by default (for struct ), so ...

... some suggested that the rule Three could actually be executed by the compiler; or, at least, since changing existing behavior can break existing code, that the rule 3 pendant can be applied by the compiler whenever it comes to a move constructor or a move assignment operator (which guarantees new C ++ 11 code) .

Rule of Five:

If you define one of the following values, you must define all five:

  • destructor
  • move constructor
  • copy constructor
Thus,

was almost completely implemented as:

  • If you define a move constructor or move an assignment operator, the remaining 4 methods are implicitly removed (unless you provide them)
  • If you define a destructor, copy constructor, or copy assignment operator, the move constructor and move assignment operator are implicitly deleted (unless you provide them)

the second statement is slightly incomplete for reasons of backward compatibility with existing C ++ 98 code (which should compile as C ++ 11 without changing behavior).

+2
source

All Articles