Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 986
philsumuru Avatar asked Feb 04 '17 07:02

philsumuru


1 Answers

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

like image 114
Columbo Avatar answered Sep 27 '22 23:09

Columbo