6

Question

After reading tons of articles about rvalue references, I know that:

std::string&& f_wrong()
{
    std::string s("hello");
    return std::move(s);
}

is wrong, and:

std::string f_right()
{
    std::string s("hello");
    return s;
}

is sufficient for the move constructor of std::string (or any move constructible classes) to be invoked. Also, if the return value is to be used to construct an object, named return value optimization (NRVO) applies, the object will be constructed directly at the target address, so the move constructor will not be invoked:

std::string s = f_right();

My question is: when is it a good time to return by rvalue references? As far as I could think of, it seems like returning an rvalue reference doesn't makes sense except for functions like std::move() and std::forward(). Is it true?

Thanks!

References

C++0x: Do people understand rvalue references? | Pizer's Weblog

return by rvalue reference

C++11 rvalues and move semantics confusion (return statement)

Is returning by rvalue reference more efficient?

Community
  • 1
  • 1
  • I agree with you,it seems like returning an rvalue reference doesn't makes sense except for functions like std::move() and std::forward(). – Ron Tang Mar 30 '15 at 01:47
  • Returning an rvalue reference is also dangerous because the returned reference cannot extend the lifetime of the object it refers to. Compare `int&& x = int();` to `int&& x = std::move( int() );` This causes problems like the following: http://programmers.stackexchange.com/q/262215/ – dyp Mar 30 '15 at 01:55
  • Perhaps when you have an rvalue-reference qualified member function it would be preferable to `std::move()` a data member out instead of incurring a (possibly non-elided) copy. (i.e `Widget&& widget() && { return std::move(m_widget); }`) – David G Mar 30 '15 at 01:57
  • 2
    see http://stackoverflow.com/a/5770888/3093378 for an answer by @Howard Hinnant about the exactly same question – vsoftco Mar 30 '15 at 02:02
  • @0x499602D2 : I also read the EMC++ book. As far as I know, if the function is return-by-value, the return value is either copy-constructed or move-constructed, depending on the situation: If it is move-constructible, the return value is move constructed; else if it is copy-constructible, the return value is copy constructed; else it is a compilation error. When NRVO applies, either copy or move construction is elided. So, if `m_widget` is move-constructible, even NRVO does not apply, the move constructor, instead of the copy constructor, will still be invoked when it is returned. – Siu Ching Pong -Asuka Kenji- Mar 30 '15 at 02:13
  • @SiuChingPong-AsukaKenji- But not if it's a data member. If it was a local variable declared within the body, then yes, move and copy constructors are considered. But only copy constructors otherwise. – David G Mar 30 '15 at 02:20
  • @0x499602D2 : I see your point now, thanks! :) – Siu Ching Pong -Asuka Kenji- Mar 30 '15 at 02:22

0 Answers0