I am trying to understand the differences of value categories and I found this document by Microsoft.
- An xvalue is a glvalue that [...]
- An lvalue is a glvalue that is not an xvalue.
- An rvalue is a prvalue or an xvalue.
Why is an xvalue
a glvalue
? Why didn't they say An xvalue is an glvalue or an rvalue
? It seems to me that this phrasing was intentionally made to convey something, but I don't understand why
Why didn't they say An xvalue is an glvalue or an rvalue?
Because rvalue had not been defined yet and because rvalue would be defined in terms of xvalue. One has to be defined without relying on the other to avoid the definition from becoming circular.
Also because xvalue is both a glvalue and an rvalue.
Furthermore, xvalue is a glvalue that is not an lvalue. Even further, xvalue is an rvalue that is not a prvalue. Lastly, xvalue is an expression that is neither lvalue nor prvalue.
I don't understand why they only mentioned gvalues in that sentence
Only glvalue and prvalue had been defined. See earlier mention of avoiding circular definition.
What are xvalues in C++
Well, you've seen its definition. The standard has following non-normative note that gives further information:
[basic.lval]
[ 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 ([expr.call]),
- a cast to an rvalue reference to object type ([expr.type.conv], [expr.dynamic.cast], [expr.static.cast] [expr.reinterpret.cast], [expr.const.cast], [expr.cast]),
- a subscripting operation with an xvalue array operand ([expr.sub]),
- a class member access expression designating a non-static data member of non-reference type in which the object expression is an xvalue ([expr.ref]), or
- a .* pointer-to-member expression in which the first operand is an xvalue and the second operand is a pointer to data member ([expr.mptr.oper]).