标准(2003)中有一个部分Ambiguity resolution
专门用于此类语法。如果您自己阅读该部分,我想我不需要进一步解释,因为它非常清楚,有很多例子!
所以你去:
8.2 歧义解决 [dcl.ambig.res]
1 - 由于函数样式转换和 6.8 中提到的声明之间的相似性而产生的歧义也可能出现在声明的上下文中。在这种情况下,选择是在参数名称周围带有一组冗余括号的函数声明和以函数样式强制转换作为初始值设定项的对象声明之间进行选择。就像 6.8 中提到的歧义一样,解决方案是将任何可能是声明的构造视为声明。[注意:声明可以通过非函数式强制转换、= 表示初始化或删除参数名称周围的冗余括号来明确消除歧义。]
[Example:
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
}
—end example]
2 - 由函数样式转换和类型标识之间的相似性引起的歧义可能出现在不同的上下文中。歧义表现为函数式强制转换表达式和类型声明之间的选择。解决方案是任何在其句法上下文中可能是类型标识的构造都应被视为类型标识。
3- [Example:
#include <cstddef>
char *p;
void *operator new(size_t, int);
void foo() {
const int x = 63;
new (int(*p)) int; // new-placement expression
new (int(*[x])); // new type-id
}
//4 - For another example,
template <class T>
struct S {
T *p;
};
S<int()> x; // type-id
S<int(1)> y; // expression (ill-formed)
//5 - For another example,
void foo()
{
sizeof(int(1)); // expression
sizeof(int()); // type-id (ill-formed)
}
//6 - For another example,
void foo()
{
(int(1)); //expression
(int())1; //type-id (ill-formed)
}
—end example]
7 - 当类型名称嵌套在括号中时,另一个歧义出现在函数声明的参数声明子句中,或者作为 sizeof 或 typeid 运算符的操作数的类型 ID 中。在这种情况下,选择是在声明函数指针类型的参数和声明在 declarator-id 周围带有冗余括号的参数之间进行选择。解决方法是将类型名称视为简单类型说明符而不是声明符 ID。
[Example:
class C { };
void f(int(C)) { } // void f(int (*fp)(C c)) { }
// not: void f(int C);
int g(C);
void foo() {
f(1); //error: cannot convert 1 to function pointer
f(g); //OK
}
//For another example,
class C { };
void h(int *(C[10])); // void h(int *(*_fp)(C _parm[10]));
// not: void h(int *C[10]);
—end example]