tmp/tmp29pajzdb/{from.md → to.md}
RENAMED
|
@@ -5,87 +5,76 @@ and a declaration mentioned in [[stmt.ambig]] can also occur in the
|
|
| 5 |
context of a declaration. In that context, the choice is between a
|
| 6 |
function declaration with a redundant set of parentheses around a
|
| 7 |
parameter name and an object declaration with a function-style cast as
|
| 8 |
the initializer. Just as for the ambiguities mentioned in
|
| 9 |
[[stmt.ambig]], the resolution is to consider any construct that could
|
| 10 |
-
possibly be a declaration a declaration.
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
|
| 15 |
``` cpp
|
| 16 |
struct S {
|
| 17 |
S(int);
|
| 18 |
};
|
| 19 |
|
| 20 |
void foo(double a) {
|
| 21 |
S w(int(a)); // function declaration
|
| 22 |
S x(int()); // function declaration
|
|
|
|
| 23 |
S y((int)a); // object declaration
|
| 24 |
S z = int(a); // object declaration
|
| 25 |
}
|
| 26 |
```
|
| 27 |
|
| 28 |
-
|
| 29 |
-
and a *type-id* can occur in different contexts. The ambiguity appears
|
| 30 |
-
as a choice between a function-style cast expression and a declaration
|
| 31 |
-
of a type. The resolution is that any construct that could possibly be a
|
| 32 |
-
*type-id* in its syntactic context shall be considered a *type-id*.
|
| 33 |
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
void foo() {
|
| 39 |
-
const int x = 63;
|
| 40 |
-
new (int(*p)) int; // new-placement expression
|
| 41 |
-
new (int(*[x])); // new type-id
|
| 42 |
-
}
|
| 43 |
-
```
|
| 44 |
|
| 45 |
-
|
| 46 |
|
| 47 |
``` cpp
|
| 48 |
-
template <class T>
|
| 49 |
-
struct
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
```
|
| 55 |
-
|
| 56 |
-
For another example,
|
| 57 |
|
| 58 |
-
|
| 59 |
-
void foo() {
|
| 60 |
-
sizeof(int(1)); // expression
|
| 61 |
sizeof(int()); // type-id (ill-formed)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
}
|
| 63 |
```
|
| 64 |
|
| 65 |
-
|
| 66 |
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
|
| 74 |
-
|
| 75 |
-
function declaration, or in a *type-id* that is the operand of a
|
| 76 |
-
`sizeof` or `typeid` operator, when a *type-name* is nested in
|
| 77 |
-
parentheses. In this case, the choice is between the declaration of a
|
| 78 |
-
parameter of type pointer to function and the declaration of a parameter
|
| 79 |
-
with redundant parentheses around the *declarator-id*. The resolution is
|
| 80 |
-
to consider the *type-name* as a *simple-type-specifier* rather than a
|
| 81 |
-
*declarator-id*.
|
| 82 |
|
| 83 |
``` cpp
|
| 84 |
class C { };
|
| 85 |
void f(int(C)) { } // void f(int(*fp)(C c)) { }
|
| 86 |
-
// not: void f(int C)
|
| 87 |
|
| 88 |
int g(C);
|
| 89 |
|
| 90 |
void foo() {
|
| 91 |
f(1); // error: cannot convert 1 to function pointer
|
|
@@ -99,5 +88,7 @@ For another example,
|
|
| 99 |
class C { };
|
| 100 |
void h(int *(C[10])); // void h(int *(*_fp)(C _parm[10]));
|
| 101 |
// not: void h(int *C[10]);
|
| 102 |
```
|
| 103 |
|
|
|
|
|
|
|
|
|
| 5 |
context of a declaration. In that context, the choice is between a
|
| 6 |
function declaration with a redundant set of parentheses around a
|
| 7 |
parameter name and an object declaration with a function-style cast as
|
| 8 |
the initializer. Just as for the ambiguities mentioned in
|
| 9 |
[[stmt.ambig]], the resolution is to consider any construct that could
|
| 10 |
+
possibly be a declaration a declaration.
|
| 11 |
+
|
| 12 |
+
[*Note 1*: A declaration can be explicitly disambiguated by adding
|
| 13 |
+
parentheses around the argument. The ambiguity can be avoided by use of
|
| 14 |
+
copy-initialization or list-initialization syntax, or by use of a
|
| 15 |
+
non-function-style cast. — *end note*]
|
| 16 |
+
|
| 17 |
+
[*Example 1*:
|
| 18 |
|
| 19 |
``` cpp
|
| 20 |
struct S {
|
| 21 |
S(int);
|
| 22 |
};
|
| 23 |
|
| 24 |
void foo(double a) {
|
| 25 |
S w(int(a)); // function declaration
|
| 26 |
S x(int()); // function declaration
|
| 27 |
+
S y((int(a))); // object declaration
|
| 28 |
S y((int)a); // object declaration
|
| 29 |
S z = int(a); // object declaration
|
| 30 |
}
|
| 31 |
```
|
| 32 |
|
| 33 |
+
— *end example*]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
|
| 35 |
+
An ambiguity can arise from the similarity between a function-style cast
|
| 36 |
+
and a *type-id*. The resolution is that any construct that could
|
| 37 |
+
possibly be a *type-id* in its syntactic context shall be considered a
|
| 38 |
+
*type-id*.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
|
| 40 |
+
[*Example 2*:
|
| 41 |
|
| 42 |
``` cpp
|
| 43 |
+
template <class T> struct X {};
|
| 44 |
+
template <int N> struct Y {};
|
| 45 |
+
X<int()> a; // type-id
|
| 46 |
+
X<int(1)> b; // expression (ill-formed)
|
| 47 |
+
Y<int()> c; // type-id (ill-formed)
|
| 48 |
+
Y<int(1)> d; // expression
|
|
|
|
|
|
|
|
|
|
| 49 |
|
| 50 |
+
void foo(signed char a) {
|
|
|
|
|
|
|
| 51 |
sizeof(int()); // type-id (ill-formed)
|
| 52 |
+
sizeof(int(a)); // expression
|
| 53 |
+
sizeof(int(unsigned(a))); // type-id (ill-formed)
|
| 54 |
+
|
| 55 |
+
(int())+1; // type-id (ill-formed)
|
| 56 |
+
(int(a))+1; // expression
|
| 57 |
+
(int(unsigned(a)))+1; // type-id (ill-formed)
|
| 58 |
}
|
| 59 |
```
|
| 60 |
|
| 61 |
+
— *end example*]
|
| 62 |
|
| 63 |
+
Another ambiguity arises in a *parameter-declaration-clause* when a
|
| 64 |
+
*type-name* is nested in parentheses. In this case, the choice is
|
| 65 |
+
between the declaration of a parameter of type pointer to function and
|
| 66 |
+
the declaration of a parameter with redundant parentheses around the
|
| 67 |
+
*declarator-id*. The resolution is to consider the *type-name* as a
|
| 68 |
+
*simple-type-specifier* rather than a *declarator-id*.
|
| 69 |
|
| 70 |
+
[*Example 3*:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
|
| 72 |
``` cpp
|
| 73 |
class C { };
|
| 74 |
void f(int(C)) { } // void f(int(*fp)(C c)) { }
|
| 75 |
+
// not: void f(int C) { }
|
| 76 |
|
| 77 |
int g(C);
|
| 78 |
|
| 79 |
void foo() {
|
| 80 |
f(1); // error: cannot convert 1 to function pointer
|
|
|
|
| 88 |
class C { };
|
| 89 |
void h(int *(C[10])); // void h(int *(*_fp)(C _parm[10]));
|
| 90 |
// not: void h(int *C[10]);
|
| 91 |
```
|
| 92 |
|
| 93 |
+
— *end example*]
|
| 94 |
+
|