Reputation: 4474
If I try to return a string literal from a function, I can make these two versions:
std::string get_val()
{
return "1234";
}
const std::string & get_ref()
{
return "1234";
}
However, what confuses me is that I thought you need to have a long-lived object, in order to have an lvalue reference (I am reading const std::string &
as an lvalue reference, perhaps I am mistaken).
Why does this work? Where does "1234"
live after I return from the function?
Upvotes: 0
Views: 153
Reputation: 610
std::string get_val()
{
return "1234";
}
In this case an object of string type is created and then the move constructor(mostly will say a copy but due to compiler optimization move is more likely to be called ) is called to store the value in the destined variable
const std::string & get_ref()
{
return "1234";
}
In this here you are returning a refrence to a temporary local object, so when the constructor of string done constructing the string object with "1234" and the return is called the object is destroyed after that as the object created was temporary with the local scope. It should throw an error to you
Upvotes: 1
Reputation: 2152
The second implementation is not valid.
Actually return "1234"
creates a temporary(rvalue) string object(as if it was return std::string("1234")
) which resides on the stack, and as soon as it returns the returned reference becomes a dangling reference as it was on the stack memory.
Recent compilers would make a warning like:
<source>: In function 'const string& get_ref()':
<source>:5:12: warning: returning reference to temporary [-Wreturn-local-addr]
5 | return "1234";
| ^~~~~~
Upvotes: 1