Move constructors
A move constructor is a constructor which can be called with an argument of the same class type and copies the content of the argument, possibly mutating the argument.
Contents |
[edit] Syntax
class-name ( parameter-list );
|
(1) | ||||||||
class-name ( parameter-list ) function-body
|
(2) | ||||||||
class-name ( single-parameter-list ) = default;
|
(3) | ||||||||
class-name ( parameter-list ) = delete;
|
(4) | ||||||||
class-name :: class-name ( parameter-list ) function-body
|
(5) | ||||||||
class-name :: class-name ( single-parameter-list ) = default;
|
(6) | ||||||||
class-name | - | the class whose move constructor is being declared |
parameter-list | - | a non-empty parameter list satisfying all following conditions:
|
single-parameter-list | - | a parameter list of only one parameter, which is of type T&&, const T&&, volatile T&& or const volatile T&& and does not have a default argument |
function-body | - | the function body of the move constructor |
[edit] Explanation
struct X { X(X&& other); // move constructor // X(X other); // Error: incorrect parameter type }; union Y { Y(Y&& other, int num = 1); // move constructor with multiple parameters // Y(Y&& other, int num); // Error: `num` has no default argument };
The move constructor is typically called when an object is initialized (by direct-initialization or copy-initialization) from rvalue (xvalue or prvalue)(until C++17)xvalue(since C++17) of the same type, including
- initialization: T a = std::move(b); or T a(std::move(b));, where b is of type
T
; - function argument passing: f(std::move(a));, where a is of type
T
and f is void f(T t); - function return: return a; inside a function such as T f(), where a is of type
T
which has a move constructor.
When the initializer is a prvalue, the move constructor call is often optimized out(until C++17)never made(since C++17), see copy elision.
Move constructors typically transfer the resources held by the argument (e.g. pointers to dynamically-allocated objects, file descriptors, TCP sockets, thread handles, etc.) rather than make copies of them, and leave the argument in some valid but otherwise indeterminate state. Since move constructor doesn’t change the lifetime of the argument, the destructor will typically be called on the argument at a later point. For example, moving from a std::string or from a std::vector may result in the argument being left empty. For some types, such as std::unique_ptr, the moved-from state is fully specified.