我在Cpp Quiz [问题#38]
看到了一个代码#include <iostream>
struct Foo
{
Foo(int d) : x(d) {}
int x;
};
int main()
{
double x = 3.14;
Foo f( int(x) );
std::cout << f.x << std::endl;
return 0;
}
据说这个代码生成错误,因为Foo f( int(x) );
将被视为函数声明而不是类型Foo
的对象声明。据我所知,这是最令人烦恼的解析的一个例子。我的问题是语句Foo f( int(x) );
中的语法 int(x) 是什么意思?到目前为止,我只看到了函数声明:
Foo f( int );
和
Foo f( int x );
与Foo f( int x );
相同吗?
答案 0 :(得分:4)
问题是,由于我不知道的原因,将参数名称包装在原型的括号中是有效的。所以
Foo f(int(x));
可以解释为
Foo f(int x);
被视为
Foo f(int);
然而,真正的问题是C ++作者,也是出于我不知道的原因,决定为几乎完全相同的语义(实例初始化)提供两种不同的语法形式很酷。
这引入了语法模糊性,并且已经解决了#34;通过说&#34;如果某事既可以是宣言又是定义,那么它就是宣言&#34;,触发了陷阱。
因此,C ++解析器必须能够解析任意大量的令牌,然后才能确定第一个令牌的语义含义。
除了编译器编写者之外,这显然不会是一个问题,但是这意味着读取C ++代码以理解它的人也必须能够做同样的事情,而对于我们这些人来说这更难。从那个&#34;最烦恼的&#34;。
答案 1 :(得分:2)
语句
int(x)
中的语法Foo f( int(x) );
是什么意思?
x
周围的括号是多余的,将被忽略。因此,int(x)
与此处的int x
相同,表示名为x
且参数类型为int
的参数。
与
Foo f( int x );
相同吗?
是。 Foo f( int(x) );
是一个名为f
的函数声明,返回Foo
,带有一个名为x
的参数int
。
这是标准的解释。 $8.2/1 Ambiguity resolution [dcl.ambig.res]:
(强调我的)
功能风格之间相似性产生的模糊性 演员和[stmt.ambig]中提到的声明也可能出现在 声明的背景。在这种情况下,选择是在a之间 带有一组冗余括号的函数声明 参数名称和具有函数样式转换为的对象声明 初始化器。就像在提到的含糊不清一样 [stmt.ambig],决议是考虑任何可能的构造 可能是宣言声明。 [注意:声明可以是 通过在参数周围添加括号来明确消除歧义。 通过使用复制初始化或可以避免歧义 列表初始化语法,或使用非函数样式转换。 - 结束语] [例子:
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)
将被视为(参数)声明而不是函数样式转换。