Prior to C++11 we only had references i.e. A Reference variable is an alias that always points to a an existing variable i.e.
int x = 7;
int & refX = x; // refX is a reference
With C++11 this reference has become lvalue reference and it can refer to lvalues only i.e.
int & lvalueRef = x; // lvalueRef is a lvalue reference
Here, lvalueRef is a lvalue reference pointing to a lvalue x. A lvalue reference can not point to a rvalue i.e.
int & lvalueRef2 = (x+1); // COMPILE Error – lvalue Reference Can’t point to rvalue
Here lvalueRef2 is a lvalue reference, so it cannot point to a rvalue.
rvalue references are introduced in C++11 and rvalue references can do what lvalue references fails to do i.e. a rvalue reference can refer to rvalues.
Declaring rvalue reference
To declare a rvalue reference, we need to specify two & operator i.e. &&.
int && rvalueRef = (x+1); // rvalueRef is rvalue reference
Here, rvalueRef is rvalue reference which is pointing to a rvalue i.e. (x+1).
Let’s see an another example,
getData() is a rvalue. So, only rvalue reference can refer to it. If lvalue reference will try to refer to it then will result in compile error i.e.
int & lvalueRef3 = getData(); // Compile error – lvalue Reference Can’t point to rvalue
Although const lvalue reference can refer to temporary object returned by getData() but as its a const reference, so we can not modify this temporary.
const int & lvalueRef3 = getData(); // OK but its const
But a rvalue reference can refer to rvalue without const i.e.
int && rvalueRef2 = getData();