Value categories

From cppreference.com
 
 
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements
Jump statements
Functions
function declaration
lambda function declaration
function template
inline specifier
exception specifications (deprecated)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
decltype specifier (C++11)
Specifiers
cv specifiers
storage duration specifiers
constexpr specifier (C++11)
auto specifier (C++11)
alignas specifier (C++11)
Initialization
Literals
Expressions
value categories
order of evaluation
alternative representations
Utilities
Types
typedef declaration
type alias declaration (C++11)
attributes (C++11)
Casts
implicit conversions
const_cast conversion
static_cast conversion
dynamic_cast conversion
reinterpret_cast conversion
C-style and functional cast
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
class template
function template
template specialization
parameter packs (C++11)
Miscellaneous
Inline assembly
 

Each C++ expression (an operator with its arguments, a literal, a variable name, etc) is characterized by two independent properties: a type and a value category. Each expression has some non-reference type, and each expression belongs to exactly one of the three primary value categories.

Contents

[edit] Primary categories

[edit] lvalue

An lvalue is an expression that identifies a non-temporary object or a non-member function.

The following expressions are lvalues:

  • The name of an object or function in scope, regardless of type, such as std::cin or std::endl. Even if the object's type is rvalue reference, the expression consisting of its name is an lvalue expression.
  • Function call or operator expression if the function's or operator's return type is an lvalue reference, such as std::getline(cin, str) or cout << 1 or a = b or ++n or *p
  • Cast expression to lvalue reference type.
  • String literal
  • Function call expression if the function's return type is rvalue reference to function type (rare)
  • Cast expression to rvalue reference to function.

Properties:

  • Same as glvalue (below)
  • Address of an lvalue may be taken: &++i and &std::endl are valid expressions.
  • A modifiable lvalue may be used as the first (left) argument of the built-in assignment operator.
  • An lvalue may be used to initialize an lvalue reference; this associates a new name with the object identified by the expression.

[edit] rvalue (until C++11) / prvalue (since C++11)

A prvalue ("pure" rvalue) is an expression that identifies a temporary object (or a subobject thereof) or is a value not associated with any object.

The following expressions are prvalues:

  • Literal (except string literal), such as 42 or true or nullptr.
  • Function call/operator expression if the function's or the operator's return type is not a reference, such as str.substr(1, 2) or 2+2
  • Cast expression to any type other than reference type.
  • Lambda expressions, such as  [](int x){return x*x;}

Properties:

  • Same as rvalue (below)
  • a prvalue cannot be polymorphic: the dynamic type of the object it identifies is always the type of the expression.
  • a non-class prvalue cannot be const-qualified.

[edit] xvalue (since C++11)

An xvalue is an expression that identifies an "eXpiring" object, that is, the object that may be moved from. The object identified by an xvalue expression may be a nameless temporary, it may be a named object in scope, or any other kind of object, but if used as a function argument, xvalue will always bind to the rvalue reference overload if available.

Only the following expressions are xvalues:

  • A function call expression, if the function's return type is an rvalue reference to object type, such as std::move(val)
  • A cast expression to an rvalue reference to object type, such as static_cast<T&&>(val) or (T&&)val
  • a non-static class member access expression, in which the object expression is an xvalue
  • A pointer-to-member expression in which the first operand is an xvalue and the second operand is a pointer to data member.

Properties:

  • Same as rvalue (below)
  • Same as glvalue (below)

Like prvalues, xvalues bind to rvalue references, but unlike prvalues, an xvalue may be polymorphic, and a non-class xvalue may be cv-qualified.

[edit] Mixed categories

[edit] glvalue(since C++11)

A glvalue ("generalized" lvalue) is an expression that is either an lvalue or an xvalue.

Properties:

  • A glvalue may be implicitly converted to prvalue with lvalue-to-rvalue, array-to-pointer, or function-to-pointer implicit conversion.
  • A glvalue may be polymorphic: the dynamic type of the object it identifies is not necessarily the static type of the expression.

[edit] rvalue (since C++11)

An rvalue is an expression that is either a prvalue or an xvalue.

Properties (note, these apply to both xvalues and prvalues, which means they apply to the pre-C++11 rvalues as well)

  • Address of an rvalue may not be taken: &i++ and &42 and &std::move(val) are invalid.
  • An rvalue may be used to initialize a const lvalue reference, in which case the lifetime of the object identified by the rvalue is extended until the scope of the reference ends.
  • An rvalue may be used to initialize an rvalue reference, in which case the lifetime of the object identified by the rvalue is extended until the scope of the reference ends.
  • When used as a function argument and when two overloads of the function are available, one taking rvalue reference parameter and the other taking lvalue reference to const parameter, rvalues bind to the rvalue reference overload (thus, if both copy and move constructors are available, rvalue arguments invoke the move constructor, and likewise with copy and move assignment operators).

[edit] Special categories

[edit] Pending member function call

The expressions obj.func and ptr->func, where func is a non-static member function, and the expressions obj.*mfp and ptr->*mfp where mfp is a pointer to member function, are classified as prvalue expressions, but they cannot be used to initialize references, as function arguments, or for any purpose at all, except as the left-hand argument of a function call expression, e.g. (pobj->*ptr)(args).

[edit] Void expressions

Function call expressions returning void, cast expressions to void, and throw-expressions are classified as prvalue expressions, but they cannot be used to initialize references or as function arguments. They can be used in a discarded-value context (e.g. on a line of its own, as the left argument of the comma operator, etc) and in the return statement in a function returning void. In addition, throw-expressions (but not other void prvalues) may be used as the second and the third operands of the conditional operator ?:.

[edit] Bit fields

An expression that designates a bit field (e.g. s.x where s is an object of type struct S { int x:3; };) is an lvalue expression: it may be used on the left hand side of the assignment operator, but its address cannot be taken and a non-const lvalue reference cannot be bound to it. A const lvalue reference can be initialized from a bit-field lvalue, but a temporary copy of the bit-field will be made: it won't bind to the bit field directly.