Using std::move() when returning a value from a function to avoid to copy

No. Whenever a local variable in a return statement is eligible for copy elision, it binds to an rvalue re­fe­rence, and thus return t; is identical to return std::move(t); in your example with respect to which constructors are eligible.

Note however that return std::move(t); prevents the compiler from exercising copy elision, while return t; does not, and thus the latter is the preferred style. [Thanks to @Johannes for the cor­rect­ion.] If copy elision happens, the question of whether or not move construction is used becomes a moot point.

See 12.8(31, 32) in the standard.

Note also that if T has an accessible copy- but a deleted move-constructor, then return t; will not com­pile, because the move constructor must be considered first; you’d have to say something to the ef­fect of return static_cast<T&>(t); to make it work:

T f()
{
    T t;
    return t;                 // most likely elided entirely
    return std::move(t);      // uses T::T(T &&) if defined; error if deleted or inaccessible
    return static_cast<T&>(t) // uses T::T(T const &)
}

Leave a Comment