C++:R-ValueReference
lastmod 2020-01-31created 2015-03-1923 edits
In C++11, an rvalue (Rvalue) has the following definition.
- An lvalue points to some memory location, and that location can be referenced through the
&operator. Rvalues are values that are not lvalues. - Things defined as rvalue references can themselves be either lvalues or rvalues. The criterion: if it has a name, it is an lvalue; if not, it is an rvalue.
Move Semantics
Expression
- c++11 rvalue reference
- [Recommended] 4.2 Value categories (glvalue, prvalue, xvalue)
- lvalue: Left value.
- rvalue: Right value.
- xvalue: eXpiring value (more lifetime).
- glvalue: Generalized lvalue (lvalue + xvalue).
- prvalue: Pure rvalue (rvalue, but not xvalue).
Return by rvalue
- [Recommended] Stackoverflow: Is returning by rvalue reference more efficient?
- Stackoverflow: C++11 rvalues and move semantics confus
This returns a dangling reference, just like with the lvalue reference case. After the function returns, the temporary object will get destructed. You should return Beta_ab by value, like the following
Now, it's properly moving a temporary Beta_ab object into the return value of the function. If the compiler can, it will avoid the move altogether, by using RVO (return value optimization). Now, you can do the following
And it will move construct the temporary into ab, or do RVO to omit doing a move or copy altogether. I recommend you to read BoostCon09 Rvalue References 101 which explains the matter, and how (N)RVO happens to interact with this.
Your case of returning an rvalue reference would be a good idea in other occasions. Imagine you have a getAB() function which you often invoke on a temporary. It's not optimal to make it return a const lvalue reference for rvalue temporaries. You may implement it like this
struct Beta {
Beta_ab ab;
Beta_ab const& getAB() const& { return ab; }
Beta_ab && getAB() && { return move(ab); }
};
Note that move in this case is not optional, because ab is neither a local automatic nor a temporary rvalue. Now, the ref-qualifier && says that the second function is invoked on rvalue temporaries, making the following move, instead of copy
Universal reference
The C++ forums use the term forward reference, but Scott Meyers (author of Effective C++) uses universal reference instead of forward reference, a name he says he coined himself.
A universal reference applies when type deduction (Type Deduction) takes place. This covers situations such as function templates (Function Template) or auto.
Perfect Forwarding
Reference Collapsing Rule
Before C++11, making a reference to a reference variable was an error. C++11, however, introduces the following Reference Collapsing Rule.
- & of T& means: T& (an L-Value reference to an L-Value reference is an L-Value reference)
- && of T& means: T& (an R-Value reference to an L-Value reference is an L-Value reference)
- & of T&& means: T& (an L-Value reference to an R-Value reference is an L-Value reference)
- && of T&& means: T&& (an R-Value reference to an R-Value reference is an R-Value reference)
See also
Favorite site
++i and i++ are LValue and RValue)