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
. [
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));
S w(int();
S x((int(a));
S y((int)a);
S z = int(a);
S a(B()->C);
S b(auto()->C);
}
—
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. [
Example 2:
template <class T> struct X {};
template <int N> struct Y {};
X<int()> a;
X<int(1)> b;
Y<int()> c;
Y<int(1)> d;
void foo(signed char a) {
sizeof(int();
sizeof(int(a));
sizeof(int(unsigned(a));
(int()+1;
(int(a))+1;
(int(unsigned(a))+1;
}
typedef struct BB { int C[2]; } *B, C;
void g() {
sizeof(B()->C[1]);
sizeof(auto()->C[1]);
}
—
end example]
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. [
Example 3:
class C { };
void f(int(C)) { }
int g(C);
void foo() {
f(1);
f(g);
}
For another example,
class C { };
void h(int *(C[10]);
—
end example]