If X is any type, then X&& is called an rvalue reference to X .
For better distinction, the ordinary reference X& is now also called an lvalue reference.
An rvalue reference is a type that behaves much like the ordinary reference void foo(X& x); // lvalue reference overload void foo(X&& x); // rvalue reference overload X x; X foobar(); foo(x); // argument is lvalue: calls foo(X&) foo(foobar()); // argument is rvalue: calls foo(X&&)So the gist of it is: |
Rvalue references allow a function to branch at compile time (via overload resolution) on the condition "Am I being called on an lvalue or an rvalue?" |
Caveat:
As it happens so often in C++, what looks just right at first glance is still
a little shy of perfect. It turns out that in some cases, the simple exchange of
content between this and rhs in the implementation of the copy assignment
operator above is not quite good enough. We'll come back to this in Section 4,
"Forcing Move Semantics" below.
|
Note:
If you implement
void foo(X&);but not void foo(X&&);then of course the behavior is unchanged: foo can be called on l-values, but not on
r-values. If you implement
void foo(X const &);but not void foo(X&&);then again, the behavior is unchanged: foo can be called on l-values and r-values, but
it is not possible to make it distinguish between l-values and r-values. That is possible only by
implementing
void foo(X&&);as well. Finally, if you implement void foo(X&&);but neither one of void foo(X&);and void foo(X const &);then, according to the final version of C++11, foo can be called on r-values, but trying to
call it on an l-value will trigger a compile error.
|