In C++03, an expression is either an rvalue or an lvalue.
In C++11, an expression can be an:
- rvalue
- lvalue
- xvalue
- glvalue
- prvalue
Two categories have become five categories.
- What are these new categories of expressions?
- How do these new categories relate to the existing rvalue and lvalue categories?
- Are the rvalue and lvalue categories in C++0x the same as they are in C++03?
- Why are these new categories needed? Are the WG21 gods just trying to confuse us mere mortals?
I have struggled with this for a long time, until I came across the cppreference.com explanation of the value categories.
It is actually rather simple, but I find that it is often explained in a way that's hard to memorize. Here it is explained very schematically. I'll quote some parts of the page:
One addendum to the excellent answers above, on a point that confused me even after I had read Stroustrup and thought I understood the rvalue/lvalue distinction. When you see
int&& a = 3
,it's very tempting to read the
int&&
as a type and conclude thata
is an rvalue. It's not:a
has a name and is ipso facto an lvalue. Don't think of the&&
as part of the type ofa
; it's just something telling you whata
is allowed to bind to.This matters particularly for
T&&
type arguments in constructors. If you writeFoo::Foo(T&& _t) : t{_t} {}
you will copy
_t
intot
. You needFoo::Foo(T&& _t) : t{std::move(_t)} {}
if you want to move. Would that my compiler warned me when I left out themove
!INTRODUCTION
ISOC++11 (officially ISO/IEC 14882:2011) is the most recent version of the standard of the C++ programming language. It contains some new features, and concepts, for example:
If we would like to understand the concepts of the new expression value categories we have to be aware of that there are rvalue and lvalue references. It is better to know rvalues can be passed to non-const rvalue references.
We can gain some intuition of the concepts of value categories if we quote the subsection titled Lvalues and rvalues from the working draft N3337 (the most similar draft to the published ISOC++11 standard).
But I am not quite sure about that this subsection is enough to understand the concepts clearly, because "usually" is not really general, "near the end of its lifetime" is not really concrete, "involving rvalue references" is not really clear, and "Example: The result of calling a function whose return type is an rvalue reference is an xvalue." sounds like a snake is biting its tail.
PRIMARY VALUE CATEGORIES
Every expression belongs to exactly one primary value category. These value categories are lvalue, xvalue and prvalue categories.
lvalues
The expression E belongs to the lvalue category if and only if E refers to an entity that ALREADY has had an identity (address, name or alias) that makes it accessible outside of E.
xvalues
The expression E belongs to the xvalue category if and only if it is
— the result of calling a function, whether implicitly or explicitly, whose return type is an rvalue reference to the type of object being returned, or
— a cast to an rvalue reference to object type, or
— 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.
Note that the effect of the rules above is that named rvalue references to objects 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.
prvalues
The expression E belongs to the prvalue category if and only if E belongs neither to the lvalue nor to the xvalue category.
MIXED VALUE CATEGORIES
There are two further important mixed value categories. These value categories are rvalue and glvalue categories.
rvalues
The expression E belongs to the rvalue category if and only if E belongs to the xvalue category, or to the prvalue category.
Note that this definition means that the expression E belongs to the rvalue category if and only if E refers to an entity that has not had any identity that makes it accessible outside of E YET.
glvalues
The expression E belongs to the glvalue category if and only if E belongs to the lvalue category, or to the xvalue category.
A PRACTICAL RULE
Scott Meyer has published a very useful rule of thumb to distinguish rvalues from lvalues.
I don't feel that the other answers (good though many of them are) really capture the answer to this particular question. Yes, these categories and such exist to allow move semantics, but the complexity exists for one reason. This is the one inviolate rule of moving stuff in C++11:
Thou shalt move only when it is unquestionably safe to do so.
That is why these categories exist: to be able to talk about values where it is safe to move from them, and to talk about values where it is not.
In the earliest version of r-value references, movement happened easily. Too easily. Easily enough that there was a lot of potential for implicitly moving things when the user didn't really mean to.
Here are the circumstances under which it is safe to move something:
If you do this:
What does this do? In older versions of the spec, before the 5 values came in, this would provoke a move. Of course it does. You passed an rvalue reference to the constructor, and thus it binds to the constructor that takes an rvalue reference. That's obvious.
There's just one problem with this; you didn't ask to move it. Oh, you might say that the
&&
should have been a clue, but that doesn't change the fact that it broke the rule.val
isn't a temporary because temporaries don't have names. You may have extended the lifetime of the temporary, but that means it isn't temporary; it's just like any other stack variable.If it's not a temporary, and you didn't ask to move it, then moving is wrong.
The obvious solution is to make
val
an lvalue. This means that you can't move from it. OK, fine; it's named, so its an lvalue.Once you do that, you can no longer say that
SomeType&&
means the same thing everwhere. You've now made a distinction between named rvalue references and unnamed rvalue references. Well, named rvalue references are lvalues; that was our solution above. So what do we call unnamed rvalue references (the return value fromFunc
above)?It's not an lvalue, because you can't move from an lvalue. And we need to be able to move by returning a
&&
; how else could you explicitly say to move something? That is whatstd::move
returns, after all. It's not an rvalue (old-style), because it can be on the left side of an equation (things are actually a bit more complicated, see this question and the comments below). It is neither an lvalue nor an rvalue; it's a new kind of thing.What we have is a value that you can treat as an lvalue, except that it is implicitly moveable from. We call it an xvalue.
Note that xvalues are what makes us gain the other two categories of values:
A prvalue is really just the new name for the previous type of rvalue, i.e. they're the rvalues that aren't xvalues.
Glvalues are the union of xvalues and lvalues in one group, because they do share a lot of properties in common.
So really, it all comes down to xvalues and the need to restrict movement to exactly and only certain places. Those places are defined by the rvalue category; prvalues are the implicit moves, and xvalues are the explicit moves (
std::move
returns an xvalue).