在解析可能是声明或表达式的构造时 - 被称为最令人烦恼的解析歧义 - 标准说“解决方案是将任何可能是声明的构造视为声明”。
(2) 和 (4) 都是有效的声明,因此它们必须被解析为声明。(3) 和 (4) 都声明了一个foo
类型A*()
为“不带参数的函数返回指针”A
的函数
6.8 Ambiguity resolution [stmt.ambig]
在涉及表达式语句和声明的语法中存在歧义:将函数样式显式类型转换 (5.2.3) 作为其最左侧子表达式的表达式语句与第一个声明符以 (.在这些情况下,语句是声明。 [注意:要消除歧义,可能必须检查整个语句以确定它是表达式语句还是声明。这消除了许多示例的歧义。[示例:假设 T 是简单的-类型说明符(7.1.5),
T(a)->m = 7; // expression-statement
T(a)++; //expression-statement
T(a,5)<<c; //expression-statement
T(*d)(int); //declaration
T(e)[5]; //declaration
T(f) = { 1, 2 }; // declaration
T(*g)(double(3)); // declaration
在上面的最后一个例子中,指向 T 的指针 g 被初始化为 double(3)。由于语义原因,这当然是错误的,但这并不影响句法分析。——结束示例]
8.2 Ambiguity resolution [dcl.ambig.res]
由函数样式转换和 6.8 中提到的声明之间的相似性引起的歧义也可能出现在声明的上下文中。在这种情况下,选择是在参数名称周围带有一组冗余括号的函数声明和以函数样式强制转换作为初始值设定项的对象声明之间进行选择。就像 6.8 中提到的歧义一样,解决方案是将任何可能是声明的构造视为声明。[注意:声明可以通过非函数式强制转换、= 表示初始化或删除参数名称周围的冗余括号来明确消除歧义。] [例子:
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 z = int(a); // object declaration
}
——结束示例]