I read in the accepted answer here that:
[a] copy constructor and copy assignment operator won't be generated for a class that explicitly declares a move constructor or move assignment operator
I do notice (g++ 4.7.2) that if you define a move constructor, it will be used with, e.g., push_back()
, whereas if all you do is = delete
the copy constructor, you don't get an implicit move constructor -- you get an error. [...which leads me to wonder which one (move or copy) is actually used if you don't do anything explicitly...]
However, this online reference does not make the same explicit promises about the copy constructor not being implicitly defined when you define a move constructor.
So my question is, is the first quote guaranteed by the standard (including the "or")? I would prefer, with some classes which need an explicit destructor, to complete the "rule of five" with just a move constructor and a (deleted) move operator and rely on the implicit copy methods not being defined. If I can't rely on that, then I'll have to explicitly =delete
them -- but that's a lot of potentially redundant stuff.
Yes, your first quote is guaranted by the standard.
Quote from the standard (draft n3690):
An interesting follow-up is why ?
In C++98 was the Rule of Three:
This rule of thumb was created because many people only thought about releasing the resource held within the destructor, and forgot the consequences this special behavior had on copies.
When C++11 came around the corner, a number of people argued that this issue was caused by the default definition provided by the language, and that it would have been better, in hindsight, not to provide them by default. Of course, C provides them by default (for
struct
) so...... some suggested that in fact the Rule of Three could be enforced by the compiler; or at least, since changing the existing behavior might break existing code, that a pendant to the Rule of Three could be enforced by the compiler whenever talking about move constructor or move assignment operator (which guarantees new C++11 code).
The Rule of Five:
was thus nearly fully implemented as:
the second statement is slightly incomplete for backward compatibility reasons with existing C++98 code (which should compile as C++11 without a change of behavior).