From Jason Turner

[dcl.type.simple]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpuy4f7lzm/{from.md → to.md} +63 -38
tmp/tmpuy4f7lzm/{from.md → to.md} RENAMED
@@ -4,10 +4,11 @@ The simple type specifiers are
4
 
5
  ``` bnf
6
  simple-type-specifier:
7
  nested-name-specifierₒₚₜ type-name
8
  nested-name-specifier 'template' simple-template-id
 
9
  'char'
10
  'char16_t'
11
  'char32_t'
12
  'wchar_t'
13
  'bool'
@@ -35,23 +36,28 @@ type-name:
35
  decltype-specifier:
36
  'decltype' '(' expression ')'
37
  'decltype' '(' 'auto' ')'
38
  ```
39
 
40
- The `auto` specifier is a placeholder for a type to be deduced (
41
- [[dcl.spec.auto]]). The other *simple-type-specifier*s specify either a
 
 
 
 
42
  previously-declared type, a type determined from an expression, or one
43
  of the fundamental types ([[basic.fundamental]]). Table 
44
  [[tab:simple.type.specifiers]] summarizes the valid combinations of
45
  *simple-type-specifier*s and the types they specify.
46
 
47
  **Table: *simple-type-specifier*{s} and the types they specify** <a id="tab:simple.type.specifiers">[tab:simple.type.specifiers]</a>
48
 
49
- | | |
50
  | ---------------------- | -------------------------------------- |
51
  | *type-name* | the type named |
52
  | *simple-template-id* | the type as defined in~ [[temp.names]] |
 
53
  | char | ``char'' |
54
  | unsigned char | ``unsigned char'' |
55
  | signed char | ``signed char'' |
56
  | char16_t | ``char16_t'' |
57
  | char32_t | ``char32_t'' |
@@ -83,85 +89,104 @@ of the fundamental types ([[basic.fundamental]]). Table 
83
  | float | ``float'' |
84
  | double | ``double'' |
85
  | long double | ``long double'' |
86
  | void | ``void'' |
87
  | auto | placeholder for a type to be deduced |
 
88
  | decltype(*expression*) | the type as defined below |
89
 
90
 
91
- When multiple *simple-type-specifiers* are allowed, they can be freely
92
- intermixed with other *decl-specifiers* in any order. It is
93
- implementation-defined whether objects of `char` type are represented as
94
- signed or unsigned quantities. The `signed` specifier forces `char`
95
- objects to be signed; it is redundant in other contexts.
 
 
96
 
97
  For an expression `e`, the type denoted by `decltype(e)` is defined as
98
  follows:
99
 
100
- - if `e` is an unparenthesized *id-expression* or an unparenthesized
101
- class member access ([[expr.ref]]), `decltype(e)` is the type of the
102
- entity named by `e`. If there is no such entity, or if `e` names a set
103
- of overloaded functions, the program is ill-formed;
 
 
 
104
  - otherwise, if `e` is an xvalue, `decltype(e)` is `T&&`, where `T` is
105
  the type of `e`;
106
  - otherwise, if `e` is an lvalue, `decltype(e)` is `T&`, where `T` is
107
  the type of `e`;
108
  - otherwise, `decltype(e)` is the type of `e`.
109
 
110
  The operand of the `decltype` specifier is an unevaluated operand
111
  (Clause  [[expr]]).
112
 
 
 
113
  ``` cpp
114
  const int&& foo();
115
  int i;
116
  struct A { double x; };
117
  const A* a = new A();
118
- decltype(foo()) x1 = 0; // type is const int&&
119
  decltype(i) x2; // type is int
120
  decltype(a->x) x3; // type is double
121
  decltype((a->x)) x4 = x3; // type is const double&
122
  ```
123
 
124
- The rules for determining types involving `decltype(auto)` are specified
125
- in  [[dcl.spec.auto]].
126
-
127
- in the case where the operand of a *decltype-specifier* is a function
128
- call and the return type of the function is a class type, a special
129
- rule ([[expr.call]]) ensures that the return type is not required to be
130
- complete (as it would be if the call appeared in a sub-expression or
131
- outside of a *decltype-specifier*). In this context, the common purpose
132
- of writing the expression is merely to refer to its type. In that sense,
133
- a *decltype-specifier* is analogous to a use of a *typedef-name*, so the
134
- usual reasons for requiring a complete type do not apply. In particular,
135
- it is not necessary to allocate storage for a temporary object or to
136
- enforce the semantic constraints associated with invoking the type’s
137
- destructor.
 
 
 
 
 
 
 
 
 
 
138
 
139
  ``` cpp
140
  template<class T> struct A { ~A() = delete; };
141
  template<class T> auto h()
142
  -> A<T>;
143
  template<class T> auto i(T) // identity
144
  -> T;
145
  template<class T> auto f(T) // #1
146
- -> decltype(i(h<T>())); // forces completion of A<T> and implicitly uses
147
- // A<T>::~A() for the temporary introduced by the
148
- // use of h(). (A temporary is not introduced
149
- // as a result of the use of i().)
150
  template<class T> auto f(T) // #2
151
  -> void;
152
  auto g() -> void {
153
- f(42); // OK: calls #2. (#1 is not a viable candidate: type
154
- // deduction fails~([temp.deduct]) because A<int>::~{A()}
155
- // is implicitly used in its decltype-specifier)
156
  }
157
  template<class T> auto q(T)
158
- -> decltype((h<T>())); // does not force completion of A<T>; A<T>::~A() is
159
- // not implicitly used within the context of this decltype-specifier
160
  void r() {
161
- q(42); // Error: deduction against q succeeds, so overload resolution
162
- // selects the specialization ``q(T) -> decltype((h<T>())) [with T=int]''.
163
  // The return type is A<int>, so a temporary is introduced and its
164
  // destructor is used, so the program is ill-formed.
165
  }
166
  ```
167
 
 
 
 
4
 
5
  ``` bnf
6
  simple-type-specifier:
7
  nested-name-specifierₒₚₜ type-name
8
  nested-name-specifier 'template' simple-template-id
9
+ nested-name-specifierₒₚₜ template-name
10
  'char'
11
  'char16_t'
12
  'char32_t'
13
  'wchar_t'
14
  'bool'
 
36
  decltype-specifier:
37
  'decltype' '(' expression ')'
38
  'decltype' '(' 'auto' ')'
39
  ```
40
 
41
+ The *simple-type-specifier* `auto` is a placeholder for a type to be
42
+ deduced ([[dcl.spec.auto]]). A *type-specifier* of the form
43
+ `typename`ₒₚₜ *nested-name-specifier*ₒₚₜ *template-name* is a
44
+ placeholder for a deduced class type ([[dcl.type.class.deduct]]). The
45
+ *template-name* shall name a class template that is not an
46
+ injected-class-name. The other *simple-type-specifier*s specify either a
47
  previously-declared type, a type determined from an expression, or one
48
  of the fundamental types ([[basic.fundamental]]). Table 
49
  [[tab:simple.type.specifiers]] summarizes the valid combinations of
50
  *simple-type-specifier*s and the types they specify.
51
 
52
  **Table: *simple-type-specifier*{s} and the types they specify** <a id="tab:simple.type.specifiers">[tab:simple.type.specifiers]</a>
53
 
54
+ | Specifier(s) | Type |
55
  | ---------------------- | -------------------------------------- |
56
  | *type-name* | the type named |
57
  | *simple-template-id* | the type as defined in~ [[temp.names]] |
58
+ | *template-name* | placeholder for a type to be deduced |
59
  | char | ``char'' |
60
  | unsigned char | ``unsigned char'' |
61
  | signed char | ``signed char'' |
62
  | char16_t | ``char16_t'' |
63
  | char32_t | ``char32_t'' |
 
89
  | float | ``float'' |
90
  | double | ``double'' |
91
  | long double | ``long double'' |
92
  | void | ``void'' |
93
  | auto | placeholder for a type to be deduced |
94
+ | decltype(auto) | placeholder for a type to be deduced |
95
  | decltype(*expression*) | the type as defined below |
96
 
97
 
98
+ When multiple *simple-type-specifier*s are allowed, they can be freely
99
+ intermixed with other *decl-specifier*s in any order.
100
+
101
+ [*Note 1*: It is *implementation-defined* whether objects of `char`
102
+ type are represented as signed or unsigned quantities. The `signed`
103
+ specifier forces `char` objects to be signed; it is redundant in other
104
+ contexts. — *end note*]
105
 
106
  For an expression `e`, the type denoted by `decltype(e)` is defined as
107
  follows:
108
 
109
+ - if `e` is an unparenthesized *id-expression* naming a structured
110
+ binding ([[dcl.struct.bind]]), `decltype(e)` is the referenced type
111
+ as given in the specification of the structured binding declaration;
112
+ - otherwise, if `e` is an unparenthesized *id-expression* or an
113
+ unparenthesized class member access ([[expr.ref]]), `decltype(e)` is
114
+ the type of the entity named by `e`. If there is no such entity, or if
115
+ `e` names a set of overloaded functions, the program is ill-formed;
116
  - otherwise, if `e` is an xvalue, `decltype(e)` is `T&&`, where `T` is
117
  the type of `e`;
118
  - otherwise, if `e` is an lvalue, `decltype(e)` is `T&`, where `T` is
119
  the type of `e`;
120
  - otherwise, `decltype(e)` is the type of `e`.
121
 
122
  The operand of the `decltype` specifier is an unevaluated operand
123
  (Clause  [[expr]]).
124
 
125
+ [*Example 1*:
126
+
127
  ``` cpp
128
  const int&& foo();
129
  int i;
130
  struct A { double x; };
131
  const A* a = new A();
132
+ decltype(foo()) x1 = 17; // type is const int&&
133
  decltype(i) x2; // type is int
134
  decltype(a->x) x3; // type is double
135
  decltype((a->x)) x4 = x3; // type is const double&
136
  ```
137
 
138
+ *end example*]
139
+
140
+ [*Note 2*: The rules for determining types involving `decltype(auto)`
141
+ are specified in  [[dcl.spec.auto]]. *end note*]
142
+
143
+ If the operand of a *decltype-specifier* is a prvalue, the temporary
144
+ materialization conversion is not applied ([[conv.rval]]) and no result
145
+ object is provided for the prvalue. The type of the prvalue may be
146
+ incomplete.
147
+
148
+ [*Note 3*: As a result, storage is not allocated for the prvalue and it
149
+ is not destroyed. Thus, a class type is not instantiated as a result of
150
+ being the type of a function call in this context. In this context, the
151
+ common purpose of writing the expression is merely to refer to its type.
152
+ In that sense, a *decltype-specifier* is analogous to a use of a
153
+ *typedef-name*, so the usual reasons for requiring a complete type do
154
+ not apply. In particular, it is not necessary to allocate storage for a
155
+ temporary object or to enforce the semantic constraints associated with
156
+ invoking the type’s destructor. — *end note*]
157
+
158
+ [*Note 4*: Unlike the preceding rule, parentheses have no special
159
+ meaning in this context. — *end note*]
160
+
161
+ [*Example 2*:
162
 
163
  ``` cpp
164
  template<class T> struct A { ~A() = delete; };
165
  template<class T> auto h()
166
  -> A<T>;
167
  template<class T> auto i(T) // identity
168
  -> T;
169
  template<class T> auto f(T) // #1
170
+ -> decltype(i(h<T>())); // forces completion of A<T> and implicitly uses A<T>::~A()
171
+ // for the temporary introduced by the use of h().
172
+ // (A temporary is not introduced as a result of the use of i().)
 
173
  template<class T> auto f(T) // #2
174
  -> void;
175
  auto g() -> void {
176
+ f(42); // OK: calls #2. (#1 is not a viable candidate: type deduction
177
+ // fails~([temp.deduct]) because A<int>::~{A()} is implicitly used in its
178
+ // decltype-specifier)
179
  }
180
  template<class T> auto q(T)
181
+ -> decltype((h<T>())); // does not force completion of A<T>; A<T>::~A() is not implicitly
182
+ // used within the context of this decltype-specifier
183
  void r() {
184
+ q(42); // Error: deduction against q succeeds, so overload resolution selects
185
+ // the specialization ``q(T) -> decltype((h<T>())) [with T=int]''.
186
  // The return type is A<int>, so a temporary is introduced and its
187
  // destructor is used, so the program is ill-formed.
188
  }
189
  ```
190
 
191
+ — *end example*]
192
+