Rvalue references solve at least two problems:
The original definition of lvalues and rvalues from the earliest days of C is as follows:
An lvalue is an expression e
that may appear on the left or on the right
hand side of an assignment, whereas an rvalue is an expression that can only appear on the
right hand side of an assignment. For example,
int a = 42; int b = 43; // a and b are both l-values: a = b; // ok b = a; // ok a = a * b; // ok // a * b is an rvalue: int c = a * b; // ok, rvalue on right hand side of assignment a * b = 42; // error, rvalue on left hand side of assignment
In C++, this is still useful as a first, intuitive approach to lvalues and rvalues. However,
C++ with its user-defined types has introduced some subtleties regarding
modifiability and assignability that cause this definition to be incorrect. There is no
need for us to go further into this. Here is an alternate definition which,
although it can still be argued with, will put you in a position to tackle rvalue
references: An lvalue is an expression that refers to a memory location and allows us to take the
address of that memory location via the &
operator.
An rvalue is an expression that is not an lvalue.
Examples are:
// lvalues: // int i = 42; i = 43; // ok, i is an lvalue int* p = &i; // ok, i is an lvalue int& foo(); foo() = 42; // ok, foo() is an lvalue int* p1 = &foo(); // ok, foo() is an lvalue // rvalues: // int foobar(); int j = 0; j = foobar(); // ok, foobar() is an rvalue int* p2 = &foobar(); // error, cannot take the address of an rvalue j = 42; // ok, 42 is an rvalueIf you are interested in a rigorous definition of rvalues and lvalues, a good place to start is Mikael Kilpelnen's ACCU article on the subject.