Every C++ expression yields an lvalue or an rvalue.
string name = "algotree"; // name is lvalue
string same = name; // name and same are both lvalues.
int sum = Add (42, 44); // Here sum is an lvalue
int Add (int x, int y) { return (x + y); } // ( x + y ) is an rvalue
string name = "algotree"; // "algotree" is rvalue.
int sum = Add (42, 44); // Add (42, 44) is an rvalue.
// Below gives an error (assignment of read-only location β"algotree"β) during compilation.
// "algotree" = name;
object_1 = Object(); // Object() is an rvalue
Lvalue reference (Reference)
It T is a type, then T& is an lvalue reference to T.
In the below snippet, num is an lvalue and we are taking a reference of an lvalue in p.
Thus p is an lvalue reference.
int num = 5;
int& p = num;
int& p = 42; // Error as 42 is an rvalue
const int& p = 42; // No error is reported, as constant lvalue reference can be assigned an rvalue.
Consider another example
int Square ( int& x ) { return x * x; }
int i = 5;
int p = Square ( i );
int q = Square ( 40 ); // Error [cannot bind non-const lvalue reference of type βint&β to an rvalue of type βintβ]
// To correct the error, we define the Square functions as below
int Square ( const int& x ) { return x * x; }
Rvalue reference
It T is a type, then T&& is an rvalue reference to T.
Rvalue references feature was added with the C++11 standard.
Consider the below example.
int Square ( int&& x ) { return x * x; } // Takes an rvalue reference as a parameter.
int Square ( int& x ) { return x * x; } // Takes an lvalue reference as a parameter.
int p = Square ( 5 ); // Calls Square ( int&& x )
int n = 5;
int q = Square ( n ); // Calls Square ( int& x )