From Jason Turner

[dcl.ambig.res]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp29pajzdb/{from.md → to.md} +39 -48
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. A declaration can be explicitly
11
- disambiguated by a nonfunction-style cast, by an `=` to indicate
12
- initialization or by removing the redundant parentheses around the
13
- parameter name.
 
 
 
 
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
- The ambiguity arising from the similarity between a function-style cast
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
- ``` cpp
35
- #include <cstddef>
36
- char* p;
37
- void* operator new(std::size_t, int);
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
- For another example,
46
 
47
  ``` cpp
48
- template <class T>
49
- struct S {
50
- T* p;
51
- };
52
- S<int()> x; // type-id
53
- S<int(1)> y; // expression (ill-formed)
54
- ```
55
-
56
- For another example,
57
 
58
- ``` cpp
59
- void foo() {
60
- sizeof(int(1)); // expression
61
  sizeof(int()); // type-id (ill-formed)
 
 
 
 
 
 
62
  }
63
  ```
64
 
65
- For another example,
66
 
67
- ``` cpp
68
- void foo() {
69
- (int(1)); // expression
70
- (int())1; // type-id (ill-formed)
71
- }
72
- ```
73
 
74
- Another ambiguity arises in a *parameter-declaration-clause* of a
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
+