38

我只是想知道为什么这段代码可以在Visual Studio中正确编译(并且没有警告) 。也许结果与GCCClang相同,但不幸的是我现在无法测试它们。

struct T {
    int t;
    T() : t(0) {}
};

int main() {
    T(i_do_not_exist);
    return 0;
}
4

2 回答 2

44

T(i_do_not_exist);是一个与 具有相同含义的对象声明T i_do_not_exist;

N4567 § 6.8[stmt.ambig]p1

在涉及表达式语句s 和声明s 的语法中存在歧义:将函数样式显式类型转换 (5.2.3) 作为其最左边的子表达式的表达式语句与第一个声明符以 a 开头的声明无法区分(. 在这些情况下,声明就是声明

§ 8.3 [dcl.含义] p6

在有表格的声明T DD

( D1 )

包含的 declarator-id的类型与声明中包含的declarator - id的类型相同

T D1

括号不会改变嵌入declarator-id的类型,但它们可以改变复杂声明符的绑定。

于 2015-12-22T13:46:54.747 回答
17

因为它定义了一个类型为 T 的变量:

http://coliru.stacked-crooked.com/a/d420870b1a6490d7

#include <iostream>

struct T {
    int t;
    T() : t(0) {}
};

int main() {
    T(i_do_not_exist);
    i_do_not_exist.t = 120;
    std::cout << i_do_not_exist.t;
    return 0;
}

上面的例子看起来很傻,但这种语法是有原因的。

一个更好的例子是:

int func1();
namespace A
{
   void func1(int);
   struct X {
       friend int (::func1)();
   };
}

可能还可以找到其他示例。

于 2015-12-22T13:48:55.313 回答