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

phi*_*uru 10 c++ language-lawyer c++14 c++17

鉴于类型的定义A:

struct A { int i; };
Run Code Online (Sandbox Code Playgroud)

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

(如果E2是非引用,)...如果E1是左值,那么E1.E2是左值; 否则E1.E2xvalue ...

显然A{}.i是xvalue; 还给出了[dcl.type.simple]:

(for decltype(e),) - ...如果e是未加密码的 id-expression或未加括号的类成员访问... - 否则,如果exvalue,则decltype(e)是T &&,其中T是类型e

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

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

Col*_*mbo 4

int&&是正确的。

\n\n

您在 [expr.ref] 中引用的措辞几年前被cwg 616更改,并且没有立即被实现采用;在这里查看我的答案。基本上,编译器必须同时采用 DR 616 和关于临时表达式的论文,否则它们会破坏需要对象生命周期扩展的代码,其中我们将引用绑定到对象的成员。在旧的实现模型中,只有纯右值可以指定生命周期延长可行的对象(尽管Johannes指出的措辞中不存在这样的要求,但在N3918之前这是模糊的措辞,所以\xe2\x80\xa6)。

\n