В Стандарте (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, когда имя типа вкладывается в скобки. В этом случае выбор между объявлением параметра типа указатель на функцию и объявлением параметра с избыточными скобками вокруг идентификатора объявления.Решение состоит в том, чтобы рассматривать имя типа как спецификатор простого типа, а не как идентификатор объявления.
[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]