Clause 5, which describes the syntax of valid expressions, lists for each expression syntax the conditions in which the expression is an lvalue, an xvalue, or a prvalue. The complete list of possible xvalues from clause 5 is:
5.2.2 paragraph 10: A function call is ... an xvalue if the result type is an rvalue reference to object type.
(In the technical language of the Standard, "object type" doesn't mean the same as "class type". "Object type" includes fundamental types, pointers, and arrays, and excludes only function types. An rvalue reference to function type is always treated as an lvalue, not xvalue.)
The most notable functions which return an rvalue reference are of course std::move
and sometimes std::forward
.
5.2.5 paragraph 4: If E2
is a non-static data member ... if E1
is an xvalue, then E1.E2
is an xvalue
(On the other hand, a data member lookup E1->E2
is always an lvalue.)
Similarly, if E1
is an xvalue, then the data member lookup E1.*E2
is an xvalue:
5.5 paragraph 6: The result of a .*
expression whose second operand is a pointer to a data member is of the same value category (3.10) as its first operand.
For the various types of casts:
dynamic_cast<Type>(expr)
: 5.2.7 paragraph 2
static_cast<Type>(expr)
: 5.2.9 paragraph 1
reinterpret_cast<Type>(expr)
: 5.2.10 paragraph 1
const_cast<Type>(expr)
: 5.2.11 paragraph 1
(Type) expr
: 5.4 paragraph 1
the expression is an xvalue if and only if Type
is an rvalue reference to object type. The same is also true for Type(expr)
, since
5.2.3 paragraph 1: If the expression list [in parentheses following a type name] is a single expression, the type conversion expression is equivalent (in definedness, and if defined in meaning) to the corresponding cast expression (5.4).
(On the other hand, Type{expr}
is always a prvalue.)
Section 5.16 on the conditional operator ends up saying that A ? B : C
can sometimes be an xvalue if B and/or C is an xvalue. But the complete rules are difficult to summarize.
If an expression ends up calling a user-defined overloaded operator function, then section 5.2.2 applies to that expression, not the one that describes the built-in operator's behavior. (See the expression a + a
in the example @James posted.)