(Prompted by an answer.)
Given N3290, §7.1.6.2p4, where the list items are unnumbered, but numbered here for our convenience:
The type denoted by decltype(e) is defined as follows:
- if e is an unparenthesized id-expression or an unparenthesized class member access (5.2.5), decltype(e) is the type of the entity named by e. If there is no such entity, or if e names a set of overloaded functions, the program is ill-formed;
- otherwise, if e is an xvalue, decltype(e) is T&&, where T is the type of e;
- otherwise, if e is an lvalue, decltype(e) is T&, where T is the type of e;
- otherwise, decltype(e) is the type of e.
What is the type specified by decltype(0 + 0)?
Item 1 doesn't apply, 2 might, but if not, then 3 doesn't apply and 4 would be the result. So, what is an xvalue, and is 0 + 0 an xvalue?
§3.10p1:
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).
I don't see anything in §8.3.2 that would be helpful here, but I do know "0 + 0" doesn't involve any rvalue-references. The literal 0 is a prvalue, which is "an rvalue that is not an xvalue" (§3.10p1). I believe "0 + 0" is also a prvalue. If that's true, "decltype(0 + 0)" would be int (not int&&).
Have I missed something in my interpretation? Is this code well-formed?
decltype(0 + 0) x; // Not initialized.
The code compiles on GCC 4.7.0 20110427 and Clang 2.9 (trunk 126116). It would not be well-formed if the decltype specified an int&& type, for example.
decltype(0 + 0)
should beint
, too. – Leprechaun0 + 0
is a prvalue. lvalue = identity and not movable. xvalue = identity and movable. prvalue = no identity and movable. An xvalue is an expression that refers to an object (and objects in C++ have an unique identity, determined by address, type and lifetime), and that object may be moved from (is considered eXpiring). This is my silly explanation, of course not to be found in the spec. – Religioseint a; (int&&)a;
the xvalue the cast yields refers to an object. Another,(int&&)2;
, the temporary bound by the reference has identity. Its lifetime will end at the end of the full expression. A (non-class, non-array) prvalue has no identity. Example2
, which is no different from another2
appearing in the code, or from1+1
, etc.. – Religiose