No. Whenever a local variable in a return
statement is eligible for copy elision, it binds to an rvalue reference, 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 correction.] 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 compile, because the move constructor must be considered first; you'd have to say something to the effect 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 &)
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…