11 Declarators [dcl.decl]

11.2 Ambiguity resolution [dcl.ambig.res]

Неоднозначность, возникающая из-за сходства между приведением в стиле функции и объявлением, упомянутым в, [stmt.ambig] также может возникать в контексте объявления. В этом контексте выбор находится между объявлением функции с избыточным набором круглых скобок вокруг имени параметра и объявлением объекта с приведением в стиле функции в качестве инициализатора. Как и в случае неоднозначности, упомянутой в [stmt.ambig], резолюция должна рассматривать любую конструкцию, которая могла бы быть объявлением, объявлением. [ Note: В объявлении можно явно устранить неоднозначность, добавив круглые скобки вокруг аргумента. Двусмысленности можно избежать, используя синтаксис копирования-инициализации или инициализации списка, или используя приведение без функционального стиля. ] [end noteExample:

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
}

end example]

Неоднозначность может возникнуть из-за сходства между приведением в стиле функции и типом type-id. Решение состоит в том, что любая конструкция, которая могла бы быть a type-id в своем синтаксическом контексте, должна считаться a type-id. [Example:

template <class T> struct X {};
template <int N> struct Y {};
X<int()> a;                     // type-id
X<int(1)> b;                    // expression (ill-formed)
Y<int()> c;                     // type-id (ill-formed)
Y<int(1)> d;                    // expression

void foo(signed char a) {
  sizeof(int());                // type-id (ill-formed)
  sizeof(int(a));               // expression
  sizeof(int(unsigned(a)));     // type-id (ill-formed)

  (int())+1;                    // type-id (ill-formed)
  (int(a))+1;                   // expression
  (int(unsigned(a)))+1;         // type-id (ill-formed)
}

end example]

Другая двусмысленность возникает в случае, parameter-declaration-clauseкогда a заключено type-name в круглые скобки. В этом случае выбор находится между объявлением параметра типа указателя на функцию и объявлением параметра с избыточными круглыми скобками вокруг declarator-id. Решение состоит в том, чтобы рассматривать type-name как a, simple-type-specifier а не как a declarator-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
}

Другой пример:

class C { };
void h(int *(C[10]));           // void h(int *(*_­fp)(C _­parm[10]));
                                // not: void h(int *C[10]);

end example]