No, it's not right. You fell for the usual trap one make when discovering rvalue reference, as did Motti in the accepted answer ! (And I did this mistake too, in my earlier test with rref)
If you don't want to shoot you in the foot when dealing with rref, internalize this :
In most case, a function returning a rvalue references is as foolish as a function returning a normal reference.
Because rvalue references are... references ! So if you return a reference - rvalue or not - to "message", you return a reference to an object that was just destroyed, because it went out of scope, so you return a dangling reference. It's a bug.
Also, don't write return std::move(message) because the compiler know already that "message" is a temporary (a rvalue), so there is no need to recast it with std::move. And actually, writing return std::move(something) can prevent optimization. (at least on MSVC10 it seems to disable RVO)
So, the correct and most efficient way is :
#include <string>
std::string foo (void)
{
std::string message ("Hello!");
return message;
}
void bar (const std::string& message2)
{
if (message2 == "Bye Bye!")
return;
}
int main ()
{
bar (foo());
}
Good old C++03 :)
Because NRVO kicks in and there is no copy, no move, only one construction.