When Does Move Constructor get called?

A move constructor is called:

  • when an object initializer is std::move(something)
  • when an object initializer is std::forward<T>(something) and T 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&&)
}

Leave a Comment