The best way to do it would be to change your method to this:
std::string StringTest()
{
std::string hello_world("Testing...");
return hello_world;
}
There is no need to tell the function that the returned object should be an rvalue, this comes automatically from the value being a temporary - that is, it is not bound to any name at the call site. As such, the initialized will value already be move-constructed (unless the temporary inside the function is elided entirely), with no need for you to manually express such an intention.
Also, since your return type is std::string
, you will return by value, not by rvalue-reference, so there is no point to moving the return argument before returning. In fact, calling std::move
will have no effect other than possibly tricking your compiler to perform an additional unnecessary move-constructor before returning your value. Such a trick serves no purpose other than making your code slightly more complex and possibly slower to run.
You also do want to return by value. One reason is because of Return Value Optimization (RVO). Most compilers will do this, which means you're better off just returning a "copy" which gets elided than trying to be clever and returning a reference.
Even when RVO cannot be applied, returning it by rvalue-reference still does not change how it is returned. When the value is returned, since it is a temporary at the call site, the returned value will already be an rvalue which can be passed along by rvalue reference to whatever function needs it as an argument. For instance, if you use the return value to intialize a variable and the return value is not elided, the move constructor still be called if available. So, not much is lost by simply returning by value.
Given this, you should probably do one of these to catch the value:
auto string_test_output = StringTest();
std::string string_test_output = StringTest();