cpp/language/move constructor

A move constructor of class is a non-template  whose first parameter is, , , or , and either there are no other parameters, or the rest of the parameters all have default values.

Syntax
Where must name the current class (or current instantiation of a class template), or, when declared at namespace scope or in a friend declaration, it must be a qualified class name.

Explanation
@1@ Typical declaration of a move constructor. @2@ Forcing a move constructor to be generated by the compiler. @3@ Avoiding implicit move constructor.

The move constructor is typically called when an object is (by  or ) from  of the same type, including
 * initialization: or, where  is of type ;
 * function argument passing:, where is of type  and  is ;
 * function return: inside a function such as, where  is of type  which has a move constructor.

When the initializer is a prvalue, the move constructor call is, see.

Move constructors typically "steal" the resources held by the argument (e.g. pointers to dynamically-allocated objects, file descriptors, TCP sockets, I/O streams, running threads, etc.) rather than make copies of them, and leave the argument in some valid but otherwise indeterminate state. For example, moving from a std or from a std may result in the argument being left empty. However, this behavior should not be relied upon. For some types, such as std, the moved-from state is fully specified.

Implicitly-declared move constructor
If no user-defined move constructors are provided for a class type (,, or ), and all of the following is true:
 * there are no user-declared s;
 * there are no user-declared s;
 * there are no user-declared s;
 * there is no user-declared.

Then the compiler will declare a move constructor as a non- member of its class with the signature.

A class can have multiple move constructors, e.g. both and. If some user-defined move constructors are present, the user may still force the generation of the implicitly declared move constructor with the keyword.

The implicitly-declared (or defaulted on its first declaration) move constructor has an exception specification as described in.

Deleted implicitly-declared move constructor
The implicitly-declared or defaulted move constructor for class is defined as deleted if any of the following is true:
 * has non-static data members that cannot be moved (have deleted, inaccessible, or ambiguous move constructors);
 * has direct or virtual base class that cannot be moved (has deleted, inaccessible, or ambiguous move constructors);
 * has direct or virtual base class or a non-static data member with a deleted or inaccessible destructor;
 * is a union-like class and has a variant member with non-trivial move constructor.

A defaulted move constructor that is deleted is ignored by (otherwise it would prevent copy-initialization from rvalue).

Trivial move constructor
The move constructor for class is trivial if all of the following is true:
 * it is not user-provided (meaning, it is implicitly-defined or defaulted);
 * has no virtual member functions;
 * has no virtual base classes;
 * the move constructor selected for every direct base of is trivial;
 * the move constructor selected for every non-static class type (or array of class type) member of is trivial.

A trivial move constructor is a constructor that performs the same action as the trivial copy constructor, that is, makes a copy of the object representation as if by std. All data types compatible with the C language (POD types) are trivially movable.

Eligible move constructor
Triviality of eligible move constructors determines whether the class is an, and whether the class is a trivially copyable type.

Implicitly-defined move constructor
If the implicitly-declared move constructor is neither deleted nor trivial, it is defined (that is, a function body is generated and compiled) by the compiler if or. For types, the implicitly-defined move constructor copies the object representation (as by std). For non-union class types ( and ), the move constructor performs full member-wise move of the object's bases and non-static members, in their initialization order, using direct initialization with an argument.