There is a helpful non-normative note in the introduction to §5 (C++11 §5[expr]/6):
[ Note: An expression is an xvalue if it is:
the result of calling a function, whether implicitly or explicitly, whose return type is an rvalue reference to object type,
a cast to an rvalue reference to object type,
a class member access expression designating a non-static data member of non-reference type in which the object expression is an xvalue, or
a
.*
pointer-to-member expression in which the first operand is an xvalue and the second operand is a pointer to data member.In general, the effect of this rule is that named rvalue references are treated as lvalues and unnamed rvalue references to objects are treated as xvalues; rvalue references to functions are treated as lvalues whether named or not. —end note ]
Searching through the rest of §5, this list appears exhaustive. The list is followed by an example:
struct A { int m; }; A&& operator+(A, A); A&& f(); A a; A&& ar = static_cast<A&&>(a);
The expressions
f()
,f().m
,static_cast<A&&>(a)
, anda + a
are xvalues. The expressionar
is an lvalue.
There are two common ways to get an xvalue expression:
-
Use
std::move
to move an object.std::move
performs astatic_cast
to an rvalue reference type and returns the rvalue reference. -
Use
std::forward
to forward an rvalue.std::forward
is typically used in a function template to enable perfect forwarding of a function argument.If the argument provided to the function template was an rvalue, the parameter type will be an rvalue reference, which is an lvalue. In this case,
std::forward
performs astatic_cast
to an rvalue reference type and returns the rvalue reference.(Note: If the argument provided to the function template was an lvalue, the parameter type will be an lvalue reference and
std::forward
will return an lvalue reference.)