What are the rules for automatic generation of move operations?

From the standard Ch. 12 - Special member functions

Par 12.8 Copying and moving class objects (emphasis mine)

9 . If the definition of a class X does not explicitly declare a move constructor, one will be implicitly declared as defaulted if and only if

— X does not have a user-declared copy constructor,

— X does not have a user-declared copy assignment operator,

— X does not have a user-declared move assignment operator, and

— X does not have a user-declared destructor.

[ Note: When the move constructor is not implicitly declared or explicitly supplied, expressions that otherwise would have invoked the move constructor may instead invoke a copy constructor. —end note ]

Then 11 explains the rules for deleting the defaulted move constructor

11 . An implicitly-declared copy/move constructor is an inline public member of its class. A defaulted copy/ move constructor for a class X is defined as deleted (8.4.3) if X has:

— a variant member with a non-trivial corresponding constructor and X is a union-like class,

— a non-static data member of class type M (or array thereof) that cannot be copied/moved because overload resolution (13.3), as applied to M’s corresponding constructor, results in an ambiguity or a function that is deleted or inaccessible from the defaulted constructor,

— a direct or virtual base class B that cannot be copied/moved because overload resolution (13.3), as applied to B’s corresponding constructor, results in an ambiguity or a function that is deleted or inaccessible from the defaulted constructor,

— any direct or virtual base class or non-static data member of a type with a destructor that is deleted or inaccessible from the defaulted constructor, or,

— for the copy constructor, a non-static data member of rvalue reference type. A defaulted move constructor that is defined as deleted is ignored by overload resolution (13.3, 13.4).

[ Note: A deleted move constructor would otherwise interfere with initialization from an rvalue which can use the copy constructor instead. —end note ]


On the complexity of it all *

The rules can be somewhat overwhelming. It's good to use some technique to bypass the complexity. Examples are :

  1. Make use of the rule of zero to simplify the writing of the majority of your classes.
  2. (On implicitly deleted) Explicitly default the special member function in question; if it would have been implicitly defined as deleted, the compiler will complain.

* points made in the comments by myself (1) and dyp (2)


Nikos Athanasiou gave a good answer but I wanted to add this tool that I think is very useful.

Here is a screenshot of Howard Hinnant's presentation "Everything You Ever Wanted To Know About Move Semantics (and then some)" from ACCU 2014 conference which I think is a very good reminder of the rules of automatic generation of special members:

enter image description here

Clarification from Mr Hinnant from the comments:

The slide doesn't say it, but the red squares indicate deprecated behavior. I.e. if you don't want to depend upon deprecated behavior, then declare both of your copy members if you declare your destructor, or one of the copy members (basically follow the C++98/03 "rule of 3")

I recommend reading the slides to get the progressive construction of this table and have a detailed explanation of how and why we have this now.

Other presentations can be found there: http://accu.org/index.php/articles/1901