philsumuru philsumuru - 4 years ago 71
C++ Question

What is the correct result of decltype( (A{}.int_member) )?

Given the definition of type

A
:

struct A { int i; };


According to the specification [expr.ref] (I used n4618) :


(if
E2
is non-reference,) ...If
E1
is an lvalue, then
E1.E2
is an lvalue; otherwise
E1.E2
is an xvalue...


obviously
A{}.i
is xvalue;
also given that [dcl.type.simple] :


(for
decltype(e)
,) — ... if
e
is an unparenthesized id-expression or an unparenthesized class member access...
otherwise, if
e
is an xvalue, decltype(e) is T&&, where T is the type of
e



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?

Answer Source

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…).

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download