只是为了弄清楚会发生什么。看这个例子
int main() {
float a = 0;
{
int(a); // no-op?
a = 1;
}
cout << a;
}
它会输出什么?好吧,它会输出0
. 上面的int(a)
可以用两种不同的方式解析:
- 转换为 int 并丢弃结果
- 声明一个名为 的变量
a
。但忽略标识符周围的括号。
当出现在语句中使用函数样式转换并且看起来也像声明的这种情况时,编译器将始终将其视为声明。当它在语法上不能是一个声明时(编译器将查看整行来确定),它将被视为一个表达式。因此,我们将分配给a
上面的内部,而外部则a
为零。
现在,您的情况正是如此。A
您正在尝试(意外地)声明一个在名为的类中调用的标识符X
:
X (X::A); // parsed as X X::A;
然后编译器继续抱怨未声明的默认构造函数,因为它假设的静态是默认构造的。但是,即使您有 X 的默认构造函数,它当然仍然是错误的,因为既不A
是 X 的静态成员,也不能在块范围内定义/声明 X 的静态成员。
你可以通过做几件事使它看起来不像一个声明。首先,您可以将整个表达式用括号括起来,这使它看起来不再像一个声明。或者只是将类型转换为括号。其他答案中都提到了这两种歧义:
(X(X::A)); (X)(X::A)
当您尝试实际声明一个对象时,存在类似但明显的歧义。看这个例子:
int main() {
float a = 0;
int b(int(a)); // object or function?
}
因为int(a)
既可以是被调用参数的声明,也可以是a
浮点变量到 int 的显式转换(强制转换),编译器再次决定这是一个声明。因此,我们碰巧声明了一个名为 的函数b
,它接受一个整数参数并返回一个整数。基于上述消歧,有几种可能的消歧方法:
int b((int(a))); int b((int)a);