Value Categories

“All categories have value.”

Basics

  glvalue
(identity)

(identityless)
rvalue
(movable)
xvalue prvalue
(immovable) lvalue  
  • glvalue: (generalised lvalue) values with an identity, encapsulating lvalues and xvalues.
  • rvalue: (read/right value) values that can be moved, encapsulating xvalues and prvalues.
  • lvalue: (locator/left value) values that cannot be moved (only copied).
  • xvalue: (eXpiring value) the result of applying std::move to an lvalue.
  • prvalue: (pure rvalue) values without an identity.

Here I have provided a list of most instances of each value category:

// lvalues
int i;          // Named variables are lvalues
"Hello World!"; // String literals have lvalue type 'const char(&)[N]'
*this;          // The dereferenced 'this' pointer is an lvalue
void fn() {}    // 'fn' is an lvalue
struct { static void fn() {} }; // Static member functions are lvalues

// xvalues
std::move( i );

// prvalues
42; true; nullptr; // Literals are prvalues (except for string literals)
enum { val };      // Enum values are prvalues
i++;               // Post-increment/decrement expressions are prvalues
&i;                // A variable's address is a prvalue
int{};             // Temporary materialisation results in a prvalue
this;              // The 'this' pointer is a prvalue
struct { void fn() {} }; // Non-static member functions are prvalues
// Arithmetic, logical, and comparison expressions also result in prvalues
// Note that the above refers to built-in operations, not user-defined overloads

Conversions always result in a prvalue, demonstrated with the following code snippet:

void fn( int&& ) {}
void fn( float&& ) {}

int main()
{
    int i{};
    // 'i' cannot find an appropriate 'fn' overload taking an lvalue 'int'
    // 'i' can be implicitly converted to 'float&&'
    // Thus, 'fn( float&& )` is invoked
    fn( i );
}

Values have an identity if they have an accessible address.
This includes variables, the dereferenced this pointer, string literals, etc.
Values without identity (prvalues) include literals, the this pointer, temporary objects (often as the result of an expression), etc.
Such values seize to exist if they are not defined.

Moving a variable refers to reusing its resources to construct/assign another object.
For example, ownership of data pointers is transferred, instead of making a copy of the data.
Continue reading about move semantics here.

results matching ""

    No results matching ""