As we have known, in most common cases, T&& means “this is a temporary object”. However, if one wants to return a temporary object from a function, he/she can declare the function as follows:
template<class T>
T f()
{
T t;
......
return t;
}
or (Note: Not Correct)
template<class T>
T&& f()
{
T t;
......
return t;
}
But I think the latter is overdid, because the former is enough and backward compatible.
Yet, I also find the std::forward()‘s return type is declared as T&&, so I’m sure my understanding about this is incomplete.
My real question is: When and where should we declare the return type of a function as T&&?
In your example, the
T&&is wrong, it’s a dangling reference.But
std::forwarddoesn’t return an rvalue reference to a local variable in its own definition, it returns an rvalue reference to its by-rvalue-reference argument (or an lvalue reference to a by-lvalue-reference argument).You should return an rvalue reference only if you want the caller of your function to be able to move from whatever that reference refers to.
Normally that will only be if the purpose of the function is to provide move access to some significant object (perhaps which already exists). So that includes
std::move(which allows you to move from an lvalue), and similarly you might write an accessor function specifically designed for users to move from a data member of some object, or an element of some container. If the object itself isn’t significant, only the value, then you can return by value.As grizzly says, sometimes due to reference collapsing you can take advantage of tricks which mean that you type
T&&in your code, but whenTis already an lvalue-reference typeT&&is the same lvalue reference type.std::forwarduses that trick. That is to say, because of reference collapsingT&&doesn’t mean “rvalue reference to T”, it means “T if T is a reference type, otherwise rvalue reference to T”.