Expression which evaluates to an identifier to some object (function, etc.) is known as lvalue or left value or locator value. For example,

int x {1};
x;

x in second line is an lvalue which evaluates to be a variable x. It is persisted in the whole scope it is declared.

Rvalue is an expression which evaluates to a value which is temporary and should be use immediately as it only exists till the expression evaluation gets completed. Rvalues are not identifiable i.e. they are not referenced by any variable as been done with Lvalues. Literals (except C-style string), return value of functions and operators that return by values are Rvalues.

For example,

std::cout << 1 + 1;

1 + 1 evaluates to 1 which is a value.

Lvalue and Rvalue with Assignment

Assignment operator expects an lvalue to be on the left side because lvalue evaluates to some identifier to which the value from right side can be assigned.

x = 1; // works
1 = x; // fails. rvalue not allowed on left side.

When lvalue is used on right side, it gets converted to rvalue by evaluating it. For example,

x = y;

where y is an lvalue that gets converted to rvalue by evaluating it and then assigned to x.

A little detour

An expression has two properties:

  1. type property
  2. value category property

Type property is the datatype of value the expression evaluates to. For example, 4 / 2 evaluates to 2 which is int.

Value category property indicates whether expression evaluates to a value, a function, or any object.

lvalue and rvalue are two value categories prior to C++11. In C++11, there are three additional value categories glvalue, prvalue, and xvalue. These new categories were added to support move semantic feature.

References

  1. https://www.learncpp.com/cpp-tutorial/value-categories-lvalues-and-rvalues/