N3174 seems to have been a proposal that introduced a rule declared by the user dtor / copy op => no implicit move. In this article, Bjarne Straustrup shows concern for certain class invariants, as in:
class Vec { vector<int> v; int my_int;
Vec has what I call an implicit invariant: there is a relationship between two objects (here, members) that are not specified anywhere declaratively in the code.
Please note that this invariant is broken by move operations, which is especially malicious if they are implicitly generated and change the value of code that was previously well executed (in C ++ 03, where rvalues are copied).
Because of these invariants, Straustrup suggested:
- Moving and copying are generated by default (if only if their elements are moved or copied, as indicated in the FCD [dyp: FCD = draft final committee])
- If any move, copy, or destructor is explicitly specified (declared, defined,
=default or =delete ) by the user, the copy or move will not be generated by default.
(Later, he suggests only abandoning the implicit generation of a copy in 2., and not completely remove it in C ++ 11)
The best explanation I can find in N3174 why the default user-declared operations are included in the second marker point is the relationship between invariants and special member functions:
I think the most disturbing cases are equivalent to Vec . There is an implicit invariant for such classes, but no “hints” to help the compiler [dyp: detecting the existence of an invariant] in the form of a custom copy constructor. This kind of example, for example, occurs when a programmer decided that the default copy operations were correct, and then (correctly) decided not to mention them because the default copy operations are superior to user-defined ones (for example, due to problems with ABI). In C ++ 0x, a programmer may be explicit by default, but this might be considered undesirable verbose.
So, by writing Vec as follows:
class Vec { vector<int> v; int my_int;
You can specify that copy operations are safe by default, and move operations by default are unsafe. If the user had to explicitly define the move operations as deleted, this will “leave a [..] hole in the expressions” (see N3053 : trying to copy or return (not const) rvalues will try to use the remote move operations.
It is not clear why dtor should be included in this list, but I think that it belongs to a group of 3/5 special member functions, where class invariants often arise.