Reputation: 65
Since we can pass rvalue to function taking const left ref,
void taking(const string& ref) {}
taking("abc");
can we return rvalue as const left ref without reporting warning?
const string& returning()
{
static string s = "abc";
if (1)
{
return s;
}
else
{
return "xyz"; // warning: return-local-addr
}
}
cout<<returning()<<endl;
Upvotes: 0
Views: 524
Reputation: 76658
The issue is not the value category (lvalue vs rvalue), but the fact that you return a reference at all.
It doesn't matter what kind of reference. When the function returns, the object that the return value is referencing, will be gone. In the case of return s;
that is the local variable and in the case of return "xyz";
it is the temporary constructed in the return statement (which must be constructed because "xyz"
itself is not a string
and so cannot be bound to const string&
).
You must return-by-value:
string returning()
If you do so, then an expression of the form returning()
will be a prvalue (a kind of rvalue) and can be used e.g. in a function expecting a const
lvalue reference, which can also bind to rvalues.
taking(returning()) // ok!
This is ok, because the return value of the function itself is not destroyed when the function exits (that would be nonsensical). Instead it lives until the end of the full expression in which the function was called.
There are also no unnecessary copies of the object being made due to copy elision rules (except for an unlikely extra move operation in return s;
).
Upvotes: 1