C++ 最烦人的解析
我在[问题38]这里看到了一个代码C++ 最烦人的解析,c++,most-vexing-parse,C++,Most Vexing Parse,我在[问题38]这里看到了一个代码 #包括 结构Foo { Foo(intd):x(d){} int x; }; int main() { 双x=3.14; Foo f(int(x)); 标准::cout 语句Foo f(int(x));中的语法int(x)是什么意思 x周围的括号是多余的,将被忽略。因此int(x)与这里的int x相同,这意味着类型为int的名为x的参数 它与Foo f(intx);相同吗 是。Foo f(int(x));是一个名为f的函数声明,返回Foo,获取一个名为x的
#包括
结构Foo
{
Foo(intd):x(d){}
int x;
};
int main()
{
双x=3.14;
Foo f(int(x));
标准::cout
语句Foo f(int(x));
中的语法int(x)
是什么意思
x
周围的括号是多余的,将被忽略。因此int(x)
与这里的int x
相同,这意味着类型为int
的名为x
的参数
它与Foo f(intx);
相同吗
是。Foo f(int(x));
是一个名为f
的函数声明,返回Foo
,获取一个名为x
的参数,类型为int
以下是标准的解释:
(强调矿山)
由于函数样式之间的相似性而产生的歧义
cast和[stmt.ambig]中提到的声明也可以出现在
声明的上下文。在该上下文中,选择是
函数声明,在
参数名和具有函数样式转换为的对象声明
初始值设定项。正如中提到的歧义
[StM.AbBug ],<强>分辨率是考虑任何可能的构造。
可能是一个声明
注:声明可以是
通过在参数周围添加括号来明确消除歧义。
可以通过使用复制初始化或
列出初始化语法,或使用非函数样式转换
struct S {
S(int);
};
void foo(double a) {
S w(int(a)); // function declaration
S x(int()); // function declaration
S y((int(a))); // object declaration
S y((int)a); // object declaration
S z = int(a); // object declaration
}
因此,int(x)
将被视为(参数的)声明,而不是函数样式转换
struct S {
S(int);
};
void foo(double a) {
S w(int(a)); // function declaration
S x(int()); // function declaration
S y((int(a))); // object declaration
S y((int)a); // object declaration
S z = int(a); // object declaration
}
语句Foo f(int(x));
中的语法int(x)
是什么意思
x
周围的括号是多余的,将被忽略。因此int(x)
与这里的int x
相同,这意味着类型为int
的名为x
的参数
它与Foo f(intx);
相同吗
是。Foo f(int(x));
是一个名为f
的函数声明,返回Foo
,获取一个名为x
的参数,类型为int
以下是标准的解释:
(强调矿山)
由于函数样式之间的相似性而产生的歧义
cast和[stmt.ambig]中提到的声明也可以出现在
声明的上下文。在该上下文中,选择是
函数声明,在
参数名和具有函数样式转换为的对象声明
初始值设定项。正如中提到的歧义
[StM.AbBug ],<强>分辨率是考虑任何可能的构造。
可能是一个声明
注:声明可以是
通过在参数周围添加括号来明确消除歧义。
可以通过使用复制初始化或
列出初始化语法,或使用非函数样式转换
struct S {
S(int);
};
void foo(double a) {
S w(int(a)); // function declaration
S x(int()); // function declaration
S y((int(a))); // object declaration
S y((int)a); // object declaration
S z = int(a); // object declaration
}
因此,int(x)
将被视为(参数的)声明,而不是函数样式转换。问题是,出于我不知道的原因,在原型中将参数名括在括号中是有效的。所以
struct S {
S(int);
};
void foo(double a) {
S w(int(a)); // function declaration
S x(int()); // function declaration
S y((int(a))); // object declaration
S y((int)a); // object declaration
S z = int(a); // object declaration
}
Foo f(int(x));
可以解释为
Foo f(int x);
这被认为是
Foo f(int);
真正的问题是,C++作者,也因为我不知道的原因,决定了对于几乎相同的语义(实例初始化)有两种不同的语法形式是很酷的。
这引入了一种语法歧义,通过说“如果某个东西既可以是声明也可以是定义,那么它就是声明”来“解决”,从而触发了陷阱
<>因为这样,C++解析器必须能够解析任意数量的令牌,才能决定第一个语义的含义。
这显然不是一个问题,除了编译器编写者,但这意味着,也就是谁读C++代码理解它必须能够做同样的事情,而对于我们人类来说,这更难。.
问题是,出于我不知道的原因,在原型中将参数名括在括号中是有效的
Foo f(int(x));
可以解释为
Foo f(int x);
这被认为是
Foo f(int);
真正的问题是,C++作者,也因为我不知道的原因,决定了对于几乎相同的语义(实例初始化)有两种不同的语法形式是很酷的。
这引入了一种语法歧义,通过说“如果某个东西既可以是声明也可以是定义,那么它就是声明”来“解决”,从而触发了陷阱
<>因为这样,C++解析器必须能够解析任意数量的令牌,才能决定第一个语义的含义。
这显然不是一个问题,除了编译器编写者,但这也意味着,谁读C++代码理解它必须能够做到同样的,对于我们人类来说,这是更困难的。从那“最令人烦恼的”。
允许,因为有时它是需要的-就像制作<代码> int *A(10)。
不同于int(*a)[10]
。而且没有人费心将语法限制在只需要的时候。@Boperson:我在上看到了代码,老实说,我不理解它:(.@NeonGlow规则是一样的,除了函数有两个参数,第二个是函数指针。@Songyuanyo:有意义。谢谢。这是允许的,因为有时需要它-比如使int*a[10]
不同于int(*a)[10]
。没有人费心把语法限制在需要的时候。@Boperson:我在上看到了代码,老实说我不明白:(@NeonGlow规则是一样的,除了函数有两个参数和