9 Declarations [dcl.dcl]

9.3 Declarators [dcl.decl]

9.3.3 Ambiguity resolution [dcl.ambig.res]

The ambiguity arising from the similarity between a function-style cast and a declaration mentioned in [stmt.ambig] can also occur in the context of a declaration.
In that context, the choice is between an object declaration with a function-style cast as the initializer and a declaration involving a function declarator with a redundant set of parentheses around a parameter name.
Just as for the ambiguities mentioned in [stmt.ambig], the resolution is to consider any construct, such as the potential parameter declaration, that could possibly be a declaration to be a declaration.
However, a construct that can syntactically be a declaration whose outermost declarator would match the grammar of a declarator with a trailing-return-type is a declaration only if it starts with auto.
[Note 1: 
A declaration can be explicitly disambiguated by adding parentheses around the argument.
The ambiguity can be avoided by use of copy-initialization or list-initialization syntax, or by use of a non-function-style cast.
— end note]
[Example 1: struct S { S(int); }; typedef struct BB { int C[2]; } *B, C; void foo(double a) { S v(int(a)); // function declaration S w(int()); // function declaration S x((int(a))); // object declaration S y((int)a); // object declaration S z = int(a); // object declaration S a(B()->C); // object declaration S b(auto()->C); // function declaration } — end example]
An ambiguity can arise from the similarity between a function-style cast and a type-id.
The resolution is that any construct that could possibly be a type-id in its syntactic context shall be considered a type-id.
However, a construct that can syntactically be a type-id whose outermost abstract-declarator would match the grammar of an abstract-declarator with a trailing-return-type is considered a type-id only if it starts with auto.
[Example 2: 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) } typedef struct BB { int C[2]; } *B, C; void g() { sizeof(B()->C[1]); // OK, sizeof(expression) sizeof(auto()->C[1]); // error: sizeof of a function returning an array } — end example]
Another ambiguity arises in a parameter-declaration-clause when a type-name is nested in parentheses.
In this case, the choice is between the declaration of a parameter of type pointer to function and the declaration of a parameter with redundant parentheses around the declarator-id.
The resolution is to consider the type-name as a simple-type-specifier rather than a declarator-id.
[Example 3: 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]