Given the definition of type A
:
struct A { int i; };
According to the specification [expr.ref] (I used n4618) :
(if
E2
is non-reference,) ...IfE1
is an lvalue, thenE1.E2
is an lvalue; otherwiseE1.E2
is an xvalue...
obviously A{}.i
is xvalue;
also given that [dcl.type.simple] :
(for
decltype(e)
,) — ... ife
is an unparenthesized id-expression or an unparenthesized class member access... — otherwise, ife
is an xvalue, decltype(e) is T&&, where T is the type ofe
therefore, decltype( ( A{}.i ) )
shall yields int&&.
However I tried GCC5.1 and Clang3.9, they yield int, while vs2015u3 yields int&&. Which is correct?
int&&
is correct.
The wording you cited in [expr.ref] was changed a couple years ago by cwg 616, and wasn't immediately adopted by implementations; see my answer here. Basically, compilers had to adopt DR 616 and the paper on temporary expressions simultaneously, or they'd break code in which lifetime extension of an object, where we bind a reference to the object's member, is required. In the old model of implementations, only prvalues could designate objects for which lifetime extension is viable (although no such requirement existed in wording as pointed out by Johannes, it was vague wording before N3918, so…).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With