C++11 为什么“decltype(x)”和“decltype((x))”的类型不同?

Hin*_*sum 5 variables types expression decltype c++11

我发现它们是不同的,语言标准规定了每个语句应该检索哪种类型(变量和表达式之间的差异)。但我真的很想知道为什么这两种类型应该不同?

#include<stdio.h>
int x=0;
decltype((x)) y=x;
int main()
{
    y=2;
    printf("%d,",x);
    decltype((1+2))&z=x;//OK (1+2) is an express, but why decltype should differ?
    z=3;
    printf("%d\n",x);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

运行结果是'2,3'

那么为什么decltype((int))int&设计,这里C++语言设计的考虑是什么?任何需要这种设计的语法一致性?(我不想得到“这是设计使然”)

谢谢你的解释。

Som*_*ude 2

如果您阅读例如decltype参考文献您会看到

\n\n
\n

2) 如果参数是不带括号的id 表达式或不带括号的类成员访问表达式,...

\n\n

3) 如果参数是任何其他表达式...

\n\n

...\nb) 如果表达式的值类别是左值,则decltype产生T&;

\n
\n\n

[强调我的]

\n\n

然后再往下一点注释

\n\n
\n

请注意,如果对象的名称带有括号,则它将被视为普通的左值表达式,因此decltype(x)decltype((x))通常是不同的类型。

\n
\n\n

因为您使用带括号的表达式,所以它被视为左值,这意味着上面的 3.b 处于活动状态并decltype((x))给出int&if xis int

\n\n

应该注意的是,虽然该参考文献不具有权威性,但它源自规范,并且通常是可靠且正确的。

\n\n
\n\n

来自 C++11 规范 ISO/IEC 14882:2011,第 7.1.6.2 节 [dcl.type.simple],第 4 小节:

\n\n
\n

表示的类型decltype(e)定义如下:

\n\n

\xe2\x80\x94 如果e是不带括号的 id 表达式或不带括号的类成员访问 (5.2.5),decltype(e)则为 命名的实体的类型e。如果没有这样的实体,或者e命名了一组重载函数,则该程序是格式错误的;

\n\n

\xe2\x80\x94 否则,如果e是 x 值,decltype(e)则 是T&&,其中是;T的类型e

\n\n

\xe2\x80\x94 否则,如果e是左值,decltype(e)则 是T&,其中是;T的类型e

\n\n

\xe2\x80\x94 否则,decltype(e)是类型e

\n
\n\n

并举一个例子:

\n\n
\n
struct A { double x; };\nconst A* a = new A();\n...\ndecltype((a->x)) x4 = x3; // type is const double&\n
Run Code Online (Sandbox Code Playgroud)\n
\n\n

基本上与之前链接的参考文献所说的完全一样。

\n\n

以您的示例为例,e规范中是(x)(因为您有declspec((x)))。现在第一种情况不适合,因为(x)不是未加括号的表达式。第二种情况不适合,因为(x)不是xvalue。第三种情况匹配,(x)是类型为 的左值int,导致decltype((x))int&

\n\n

因此,您的问题的答案很简单:因为规范是这么说的。

\n