I'm trying to understand the C++11 concepts.
The standard draft which I have says:
An xvalue (an “eXpiring” value) also refers to an object, usually near the end of its lifetime (so that its resources may be moved, for example). An xvalue is the result of certain kinds of expressions involving rvalue references (8.3.2). [ Example: The result of calling a function whose return type is an rvalue reference is an xvalue. —end example ]
OK, so what exactly are the "certain kinds of expressions" that produce xvalues? This part of the spec does not detail a list of these expressions.
I understand lvalue and prvalue (at least I think, I understand).
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 a static_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 a static_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.)