Prior to C++11, and as a standard programming idiom, temporaries are often assigned to variables to make the code cleaner. For small types a copy is typically made, and for larger types perhaps a reference, such as:
int a = int_func();
T const & obj = obj_func();
some_func( a, obj );
Now, compare this to the inlined form:
some_func( int_func(), obj_func() );
Prior to C++11 this had nearly identical semantic meaning. With the introduction of rvalue-reference and move semantics the above are now entirely different. In particular, by forcing obj to type T const & you have removed the ability to use a move constructor, whereas the inline form the type can be a T&& instead.
Given that the first is a common paradigm, is there anything in the standard that would allow an optimizer to use a move constructor in the first case? That is, could somehow the compiler ignore the binding to a T const & and instead treat it as a T&&, or, as I suspect, would this violate the rules of the abstract machine?
Second part of the question, to do this correctly in C++11 (without eliminating named temporaries) we need to somehow declare a proper rvalue-reference. We can also use the auto keyword. So, what is the proper way to do this? My guess is:
auto&& obj = obj_func();
Part 1:
The compiler is not allowed to implicilty transform
objinto a non-const rvalue and thus use a move constructor when callingsome_func.Part 2:
This will create a non-const reference to the temporary, but it will not be implicitly moved from when calling
some_funcbecauseobjis an lvalue. To transform it to an rvalue you should usestd::moveat the call site: