From Jason Turner

[temp.param]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpq2jbfqnl/{from.md → to.md} +135 -73
tmp/tmpq2jbfqnl/{from.md → to.md} RENAMED
@@ -10,23 +10,31 @@ template-parameter:
10
 
11
  ``` bnf
12
  type-parameter:
13
  type-parameter-key '...'ₒₚₜ identifierₒₚₜ
14
  type-parameter-key identifierₒₚₜ '=' type-id
15
- 'template <' template-parameter-list '>' type-parameter-key '...'ₒₚₜ identifierₒₚₜ
16
- 'template <' template-parameter-list '>' type-parameter-key identifierₒₚₜ '=' id-expression
 
 
17
  ```
18
 
19
  ``` bnf
20
  type-parameter-key:
21
- 'class'
22
- 'typename'
 
 
 
 
 
 
23
  ```
24
 
25
  [*Note 1*: The `>` token following the *template-parameter-list* of a
26
  *type-parameter* may be the product of replacing a `>{>}` token by two
27
- consecutive `>` tokens ([[temp.names]]). — *end note*]
28
 
29
  There is no semantic difference between `class` and `typename` in a
30
  *type-parameter-key*. `typename` followed by an *unqualified-id* names a
31
  template type parameter. `typename` followed by a *qualified-id* denotes
32
  the type in a non-type [^1] *parameter-declaration*. A
@@ -74,66 +82,112 @@ class Map {
74
  };
75
  ```
76
 
77
  — *end note*]
78
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  A non-type *template-parameter* shall have one of the following
80
- (optionally cv-qualified) types:
81
 
82
- - integral or enumeration type,
83
- - pointer to object or pointer to function,
84
- - lvalue reference to object or lvalue reference to function,
85
- - pointer to member,
86
- - `std::nullptr_t`, or
87
- - a type that contains a placeholder type ([[dcl.spec.auto]]).
88
-
89
- [*Note 3*: Other types are disallowed either explicitly below or
90
- implicitly by the rules governing the form of *template-argument*s (
91
- [[temp.arg]]). — *end note*]
92
 
93
  The top-level *cv-qualifier*s on the *template-parameter* are ignored
94
  when determining its type.
95
 
96
- A non-type non-reference *template-parameter* is a prvalue. It shall not
97
- be assigned to or in any other way have its value changed. A non-type
98
- non-reference *template-parameter* cannot have its address taken. When a
99
- non-type non-reference *template-parameter* is used as an initializer
100
- for a reference, a temporary is always used.
101
 
102
- [*Example 2*:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
 
104
  ``` cpp
105
- template<const X& x, int i> void f() {
 
 
106
  i++; // error: change of template-parameter value
107
 
108
  &x; // OK
109
  &i; // error: address of non-reference template-parameter
110
-
111
  int& ri = i; // error: non-const reference bound to temporary
112
  const int& cri = i; // OK: const reference bound to temporary
 
113
  }
114
  ```
115
 
116
  — *end example*]
117
 
118
- A non-type *template-parameter* shall not be declared to have
119
- floating-point, class, or void type.
120
 
121
- [*Example 3*:
 
 
 
122
 
123
  ``` cpp
124
- template<double d> class X; // error
125
- template<double* pd> class Y; // OK
126
- template<double& rd> class Z; // OK
127
  ```
128
 
129
  — *end example*]
130
 
 
 
131
  A non-type *template-parameter* of type “array of `T`” or of function
132
  type `T` is adjusted to be of type “pointer to `T`”.
133
 
134
- [*Example 4*:
135
 
136
  ``` cpp
137
  template<int* a> struct R { ... };
138
  template<int b[5]> struct S { ... };
139
  int p;
@@ -144,30 +198,35 @@ R<v> y; // OK due to implicit argument conversion
144
  S<v> z; // OK due to both adjustment and conversion
145
  ```
146
 
147
  — *end example*]
148
 
149
- A *default template-argument* is a *template-argument* ([[temp.arg]])
 
 
 
 
 
150
  specified after `=` in a *template-parameter*. A default
151
  *template-argument* may be specified for any kind of
152
  *template-parameter* (type, non-type, template) that is not a template
153
- parameter pack ([[temp.variadic]]). A default *template-argument* may
154
- be specified in a template declaration. A default *template-argument*
155
- shall not be specified in the *template-parameter-list*s of the
156
- definition of a member of a class template that appears outside of the
157
- member’s class. A default *template-argument* shall not be specified in
158
- a friend class template declaration. If a friend function template
159
- declaration specifies a default *template-argument*, that declaration
160
- shall be a definition and shall be the only declaration of the function
161
- template in the translation unit.
162
 
163
  The set of default *template-argument*s available for use is obtained by
164
  merging the default arguments from all prior declarations of the
165
- template in the same way default function arguments are (
166
- [[dcl.fct.default]]).
167
 
168
- [*Example 5*:
169
 
170
  ``` cpp
171
  template<class T1, class T2 = int> class A;
172
  template<class T1 = int, class T2> class A;
173
  ```
@@ -186,17 +245,17 @@ alias template has a default *template-argument*, each subsequent
186
  supplied or be a template parameter pack. If a *template-parameter* of a
187
  primary class template, primary variable template, or alias template is
188
  a template parameter pack, it shall be the last *template-parameter*. A
189
  template parameter pack of a function template shall not be followed by
190
  another template parameter unless that template parameter can be deduced
191
- from the parameter-type-list ([[dcl.fct]]) of the function template or
192
- has a default argument ([[temp.deduct]]). A template parameter of a
193
- deduction guide template ([[temp.deduct.guide]]) that does not have a
194
- default argument shall be deducible from the parameter-type-list of the
195
  deduction guide template.
196
 
197
- [*Example 6*:
198
 
199
  ``` cpp
200
  template<class T1 = int, class T2> class B; // error
201
 
202
  // U can be neither deduced from the parameter-type-list nor specified
@@ -207,11 +266,11 @@ template<class... T, class U> void g() { } // error
207
  — *end example*]
208
 
209
  A *template-parameter* shall not be given default arguments by two
210
  different declarations in the same scope.
211
 
212
- [*Example 7*:
213
 
214
  ``` cpp
215
  template<class T = int> class X;
216
  template<class T = int> class X { ... }; // error
217
  ```
@@ -220,11 +279,11 @@ template<class T = int> class X { ... }; // error
220
 
221
  When parsing a default *template-argument* for a non-type
222
  *template-parameter*, the first non-nested `>` is taken as the end of
223
  the *template-parameter-list* rather than a greater-than operator.
224
 
225
- [*Example 8*:
226
 
227
  ``` cpp
228
  template<int i = 3 > 4 > // syntax error
229
  class X { ... };
230
 
@@ -237,52 +296,55 @@ class Y { ... };
237
  A *template-parameter* of a template *template-parameter* is permitted
238
  to have a default *template-argument*. When such default arguments are
239
  specified, they apply to the template *template-parameter* in the scope
240
  of the template *template-parameter*.
241
 
242
- [*Example 9*:
243
 
244
  ``` cpp
245
- template <class T = float> struct B {};
246
  template <template <class TT = float> class T> struct A {
247
  inline void f();
248
  inline void g();
249
  };
250
  template <template <class TT> class T> void A<T>::f() {
251
- T<> t; // error - TT has no default template argument
252
  }
253
  template <template <class TT = char> class T> void A<T>::g() {
254
- T<> t; // OK - T<char>
255
  }
256
  ```
257
 
258
  — *end example*]
259
 
260
  If a *template-parameter* is a *type-parameter* with an ellipsis prior
261
  to its optional *identifier* or is a *parameter-declaration* that
262
- declares a parameter pack ([[dcl.fct]]), then the *template-parameter*
263
- is a template parameter pack ([[temp.variadic]]). A template parameter
264
- pack that is a *parameter-declaration* whose type contains one or more
265
- unexpanded parameter packs is a pack expansion. Similarly, a template
266
- parameter pack that is a *type-parameter* with a
267
- *template-parameter-list* containing one or more unexpanded parameter
268
- packs is a pack expansion. A template parameter pack that is a pack
269
- expansion shall not expand a parameter pack declared in the same
 
270
  *template-parameter-list*.
271
 
272
- [*Example 10*:
273
 
274
  ``` cpp
275
- template <class... Types> class Tuple; // Types is a template type parameter pack
276
- // but not a pack expansion
277
- template <class T, int... Dims> struct multi_array; // Dims is a non-type template parameter pack
278
- // but not a pack expansion
279
- template<class... T> struct value_holder {
 
 
 
280
  template <T... Values> struct apply { }; // Values is a non-type template parameter pack
281
- // and a pack expansion
282
- };
283
- template<class... T, T... Values> struct static_array;// error: Values expands template type parameter
284
- // pack T within the same template parameter list
285
  ```
286
 
287
  — *end example*]
288
 
 
10
 
11
  ``` bnf
12
  type-parameter:
13
  type-parameter-key '...'ₒₚₜ identifierₒₚₜ
14
  type-parameter-key identifierₒₚₜ '=' type-id
15
+ type-constraint '...'ₒₚₜ identifierₒₚₜ
16
+ type-constraint identifierₒₚₜ '=' type-id
17
+ template-head type-parameter-key '...'ₒₚₜ identifierₒₚₜ
18
+ template-head type-parameter-key identifierₒₚₜ '=' id-expression
19
  ```
20
 
21
  ``` bnf
22
  type-parameter-key:
23
+ class
24
+ typename
25
+ ```
26
+
27
+ ``` bnf
28
+ type-constraint:
29
+ nested-name-specifierₒₚₜ concept-name
30
+ nested-name-specifierₒₚₜ concept-name '<' template-argument-listₒₚₜ '>'
31
  ```
32
 
33
  [*Note 1*: The `>` token following the *template-parameter-list* of a
34
  *type-parameter* may be the product of replacing a `>{>}` token by two
35
+ consecutive `>` tokens [[temp.names]]. — *end note*]
36
 
37
  There is no semantic difference between `class` and `typename` in a
38
  *type-parameter-key*. `typename` followed by an *unqualified-id* names a
39
  template type parameter. `typename` followed by a *qualified-id* denotes
40
  the type in a non-type [^1] *parameter-declaration*. A
 
82
  };
83
  ```
84
 
85
  — *end note*]
86
 
87
+ A *type-constraint* `Q` that designates a concept `C` can be used to
88
+ constrain a contextually-determined type or template type parameter pack
89
+ `T` with a *constraint-expression* `E` defined as follows. If `Q` is of
90
+ the form `C<A₁, ⋯, Aₙ>`, then let `E'` be `C<T, A₁, ⋯, Aₙ>`. Otherwise,
91
+ let `E'` be `C<T>`. If `T` is not a pack, then `E` is `E'`, otherwise
92
+ `E` is `(E' && ...)`. This *constraint-expression* `E` is called the
93
+ *immediately-declared constraint* of `Q` for `T`. The concept designated
94
+ by a *type-constraint* shall be a type concept [[temp.concept]].
95
+
96
+ A *type-parameter* that starts with a *type-constraint* introduces the
97
+ immediately-declared constraint of the *type-constraint* for the
98
+ parameter.
99
+
100
+ [*Example 2*:
101
+
102
+ ``` cpp
103
+ template<typename T> concept C1 = true;
104
+ template<typename... Ts> concept C2 = true;
105
+ template<typename T, typename U> concept C3 = true;
106
+
107
+ template<C1 T> struct s1; // associates C1<T>
108
+ template<C1... T> struct s2; // associates (C1<T> && ...)
109
+ template<C2... T> struct s3; // associates (C2<T> && ...)
110
+ template<C3<int> T> struct s4; // associates C3<T, int>
111
+ template<C3<int>... T> struct s5; // associates (C3<T, int> && ...)
112
+ ```
113
+
114
+ — *end example*]
115
+
116
  A non-type *template-parameter* shall have one of the following
117
+ (possibly cv-qualified) types:
118
 
119
+ - a structural type (see below),
120
+ - a type that contains a placeholder type [[dcl.spec.auto]], or
121
+ - a placeholder for a deduced class type [[dcl.type.class.deduct]].
 
 
 
 
 
 
 
122
 
123
  The top-level *cv-qualifier*s on the *template-parameter* are ignored
124
  when determining its type.
125
 
126
+ A *structural type* is one of the following:
 
 
 
 
127
 
128
+ - a scalar type, or
129
+ - an lvalue reference type, or
130
+ - a literal class type with the following properties:
131
+ - all base classes and non-static data members are public and
132
+ non-mutable and
133
+ - the types of all bases classes and non-static data members are
134
+ structural types or (possibly multi-dimensional) array thereof.
135
+
136
+ An *id-expression* naming a non-type *template-parameter* of class type
137
+ `T` denotes a static storage duration object of type `const T`, known as
138
+ a *template parameter object*, whose value is that of the corresponding
139
+ template argument after it has been converted to the type of the
140
+ *template-parameter*. All such template parameters in the program of the
141
+ same type with the same value denote the same template parameter object.
142
+ A template parameter object shall have constant destruction
143
+ [[expr.const]].
144
+
145
+ [*Note 3*: If an *id-expression* names a non-type non-reference
146
+ *template-parameter*, then it is a prvalue if it has non-class type.
147
+ Otherwise, if it is of class type `T`, it is an lvalue and has type
148
+ `const T` [[expr.prim.id.unqual]]. — *end note*]
149
+
150
+ [*Example 3*:
151
 
152
  ``` cpp
153
+ using X = int;
154
+ struct A {};
155
+ template<const X& x, int i, A a> void f() {
156
  i++; // error: change of template-parameter value
157
 
158
  &x; // OK
159
  &i; // error: address of non-reference template-parameter
160
+ &a; // OK
161
  int& ri = i; // error: non-const reference bound to temporary
162
  const int& cri = i; // OK: const reference bound to temporary
163
+ const A& ra = a; // OK: const reference bound to a template parameter object
164
  }
165
  ```
166
 
167
  — *end example*]
168
 
169
+ [*Note 4*:
 
170
 
171
+ A non-type *template-parameter* cannot be declared to have type cv
172
+ `void`.
173
+
174
+ [*Example 4*:
175
 
176
  ``` cpp
177
+ template<void v> class X; // error
178
+ template<void* pv> class Y; // OK
 
179
  ```
180
 
181
  — *end example*]
182
 
183
+ — *end note*]
184
+
185
  A non-type *template-parameter* of type “array of `T`” or of function
186
  type `T` is adjusted to be of type “pointer to `T`”.
187
 
188
+ [*Example 5*:
189
 
190
  ``` cpp
191
  template<int* a> struct R { ... };
192
  template<int b[5]> struct S { ... };
193
  int p;
 
198
  S<v> z; // OK due to both adjustment and conversion
199
  ```
200
 
201
  — *end example*]
202
 
203
+ A non-type template parameter declared with a type that contains a
204
+ placeholder type with a *type-constraint* introduces the
205
+ immediately-declared constraint of the *type-constraint* for the
206
+ invented type corresponding to the placeholder [[dcl.fct]].
207
+
208
+ A *default template-argument* is a *template-argument* [[temp.arg]]
209
  specified after `=` in a *template-parameter*. A default
210
  *template-argument* may be specified for any kind of
211
  *template-parameter* (type, non-type, template) that is not a template
212
+ parameter pack [[temp.variadic]]. A default *template-argument* may be
213
+ specified in a template declaration. A default *template-argument* shall
214
+ not be specified in the *template-parameter-list*s of the definition of
215
+ a member of a class template that appears outside of the member’s class.
216
+ A default *template-argument* shall not be specified in a friend class
217
+ template declaration. If a friend function template declaration
218
+ specifies a default *template-argument*, that declaration shall be a
219
+ definition and shall be the only declaration of the function template in
220
+ the translation unit.
221
 
222
  The set of default *template-argument*s available for use is obtained by
223
  merging the default arguments from all prior declarations of the
224
+ template in the same way default function arguments are
225
+ [[dcl.fct.default]].
226
 
227
+ [*Example 6*:
228
 
229
  ``` cpp
230
  template<class T1, class T2 = int> class A;
231
  template<class T1 = int, class T2> class A;
232
  ```
 
245
  supplied or be a template parameter pack. If a *template-parameter* of a
246
  primary class template, primary variable template, or alias template is
247
  a template parameter pack, it shall be the last *template-parameter*. A
248
  template parameter pack of a function template shall not be followed by
249
  another template parameter unless that template parameter can be deduced
250
+ from the parameter-type-list [[dcl.fct]] of the function template or has
251
+ a default argument [[temp.deduct]]. A template parameter of a deduction
252
+ guide template [[temp.deduct.guide]] that does not have a default
253
+ argument shall be deducible from the parameter-type-list of the
254
  deduction guide template.
255
 
256
+ [*Example 7*:
257
 
258
  ``` cpp
259
  template<class T1 = int, class T2> class B; // error
260
 
261
  // U can be neither deduced from the parameter-type-list nor specified
 
266
  — *end example*]
267
 
268
  A *template-parameter* shall not be given default arguments by two
269
  different declarations in the same scope.
270
 
271
+ [*Example 8*:
272
 
273
  ``` cpp
274
  template<class T = int> class X;
275
  template<class T = int> class X { ... }; // error
276
  ```
 
279
 
280
  When parsing a default *template-argument* for a non-type
281
  *template-parameter*, the first non-nested `>` is taken as the end of
282
  the *template-parameter-list* rather than a greater-than operator.
283
 
284
+ [*Example 9*:
285
 
286
  ``` cpp
287
  template<int i = 3 > 4 > // syntax error
288
  class X { ... };
289
 
 
296
  A *template-parameter* of a template *template-parameter* is permitted
297
  to have a default *template-argument*. When such default arguments are
298
  specified, they apply to the template *template-parameter* in the scope
299
  of the template *template-parameter*.
300
 
301
+ [*Example 10*:
302
 
303
  ``` cpp
 
304
  template <template <class TT = float> class T> struct A {
305
  inline void f();
306
  inline void g();
307
  };
308
  template <template <class TT> class T> void A<T>::f() {
309
+ T<> t; // error: TT has no default template argument
310
  }
311
  template <template <class TT = char> class T> void A<T>::g() {
312
+ T<> t; // OK, T<char>
313
  }
314
  ```
315
 
316
  — *end example*]
317
 
318
  If a *template-parameter* is a *type-parameter* with an ellipsis prior
319
  to its optional *identifier* or is a *parameter-declaration* that
320
+ declares a pack [[dcl.fct]], then the *template-parameter* is a template
321
+ parameter pack [[temp.variadic]]. A template parameter pack that is a
322
+ *parameter-declaration* whose type contains one or more unexpanded packs
323
+ is a pack expansion. Similarly, a template parameter pack that is a
324
+ *type-parameter* with a *template-parameter-list* containing one or more
325
+ unexpanded packs is a pack expansion. A type parameter pack with a
326
+ *type-constraint* that contains an unexpanded parameter pack is a pack
327
+ expansion. A template parameter pack that is a pack expansion shall not
328
+ expand a template parameter pack declared in the same
329
  *template-parameter-list*.
330
 
331
+ [*Example 11*:
332
 
333
  ``` cpp
334
+ template <class... Types> // Types is a template type parameter pack
335
+ class Tuple; // but not a pack expansion
336
+
337
+ template <class T, int... Dims> // Dims is a non-type template parameter pack
338
+ struct multi_array; // but not a pack expansion
339
+
340
+ template <class... T>
341
+ struct value_holder {
342
  template <T... Values> struct apply { }; // Values is a non-type template parameter pack
343
+ }; // and a pack expansion
344
+
345
+ template <class... T, T... Values> // error: Values expands template type parameter
346
+ struct static_array; // pack T within the same template parameter list
347
  ```
348
 
349
  — *end example*]
350