A move constructor is called:
- when an object initializer is
std::move(something)
- when an object initializer is
std::forward<T>(something)
andT
is not an lvalue reference type (useful in template programming for “perfect forwarding”) - when an object initializer is a temporary and the compiler doesn’t eliminate the copy/move entirely
- when returning a function-local class object by value and the compiler doesn’t eliminate the copy/move entirely
- when throwing a function-local class object and the compiler doesn’t eliminate the copy/move entirely
This is not a complete list. Note that an “object initializer” can be a function argument, if the parameter has a class type (not reference).
a RetByValue() {
a obj;
return obj; // Might call move ctor, or no ctor.
}
void TakeByValue(a);
int main() {
a a1;
a a2 = a1; // copy ctor
a a3 = std::move(a1); // move ctor
TakeByValue(std::move(a2)); // Might call move ctor, or no ctor.
a a4 = RetByValue(); // Might call move ctor, or no ctor.
a1 = RetByValue(); // Calls move assignment, a::operator=(a&&)
}