According to another answer, an rvalue reference will not extend the lifetime of a temporary if the expression referring to it is an xvalue expression. Since std::move
returns an rvalue reference, the expression of calling it is an xvalue and so the following results in an a dangling reference:
int main()
{
std::string&& danger = std::move(get_string()); // dangling reference !
return 0;
}
That's fine. The std::move
doesn't make sense here; it is already an rvalue.
But here's where I'm drawing a blank. How is this different to passing an xvalue expression as an argument, completely standard use of std::move
and rvalue references?
void foo(const std::string& val);
// More efficient foo for temporaries:
void foo(std::string&& val);
int main()
{
std::string s;
foo(std::move(s)); // Give up s for efficiency
return 0;
}
Is there a special rule for rvalue reference arguments that will extend the lifetime of a temporary regardless of whether it is an prvalue or xvalue? Or is the std::move
calling expression only an xvalue because we passed it something that was already an rvalue? I don't think so because it returns an rvalue reference anyway, which is an xvalue. I'm confused here. I think I'm missing something silly.
Your second example is not passing a reference to a temporary, it's passing a reference to the variable s
, which lasts until the end of main()
.
If it were (e.g. foo(std::move(get_string()));
), then the temporary's lifetime lasts until the end of the full expression - after the function has returned. It's therefore quite safe to use it within foo
. There is only a danger if foo
stores a reference/pointer to its argument, and something else tries to use it later.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With