decltype( (A{}.int_member) ) 的正确结果是什么?

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

给定类型A的定义:

struct A { int i; };

根据规范[expr.ref](我用的是n4618):

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

显然A{}.i是xvalue; 还考虑到 [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

因此,decltype( ( A{}.i ) ) 应产生 int&&.

但是我尝试了 GCC5.1 和 Clang3.9,它们产生 int,而 vs2015u3 产生 int&&。哪个是正确的?

int&& 正确。

您在 [expr.ref] 中引用的措辞在几年前被 cwg 616, and wasn't immediately adopted by implementations; see my answer 更改了。基本上,编译器必须同时采用 DR 616 和关于临时表达式的论文,否则它们会破坏对象生命周期延长的代码,我们将引用绑定到对象的成员,是必须的。在旧的实现模型中,只有 prvalues 可以指定生命周期延长可行的对象(尽管 Johannes 指出的措辞中不存在这样的要求,但在 N3918 之前是模糊的措辞,所以......)。