From Jason Turner

[temp.arg]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpvrrxzkr1/{from.md → to.md} +36 -31
tmp/tmpvrrxzkr1/{from.md → to.md} RENAMED
@@ -172,22 +172,24 @@ shall be one of:
172
  - for a non-type *template-parameter* of integral or enumeration type, a
173
  converted constant expression ([[expr.const]]) of the type of the
174
  *template-parameter*; or
175
  - the name of a non-type *template-parameter*; or
176
  - a constant expression ([[expr.const]]) that designates the address of
177
- an object with static storage duration and external or internal
178
- linkage or a function with external or internal linkage, including
179
- function templates and function *template-id*s but excluding
180
  non-static class members, expressed (ignoring parentheses) as `&`
181
- *id-expression*, except that the `&` may be omitted if the name refers
182
- to a function or array and shall be omitted if the corresponding
 
183
  *template-parameter* is a reference; or
184
  - a constant expression that evaluates to a null pointer value (
185
  [[conv.ptr]]); or
186
  - a constant expression that evaluates to a null member pointer value (
187
  [[conv.mem]]); or
188
- - a pointer to member expressed as described in  [[expr.unary.op]].
 
189
 
190
  A string literal ([[lex.string]]) does not satisfy the requirements of
191
  any of these categories and thus is not an acceptable
192
  *template-argument*.
193
 
@@ -241,18 +243,17 @@ the program is ill-formed.
241
  - for a non-type *template-parameter* of type pointer to object,
242
  qualification conversions ([[conv.qual]]) and the array-to-pointer
243
  conversion ([[conv.array]]) are applied; if the *template-argument*
244
  is of type `std::nullptr_t`, the null pointer conversion (
245
  [[conv.ptr]]) is applied. In particular, neither the null pointer
246
- conversion for a zero-valued integral constant expression (
247
- [[conv.ptr]]) nor the derived-to-base conversion ([[conv.ptr]]) are
248
- applied. Although `0` is a valid *template-argument* for a non-type
249
- *template-parameter* of integral type, it is not a valid
250
- *template-argument* for a non-type *template-parameter* of pointer
251
- type. However, both `(int*)0` and `nullptr` are valid
252
- *template-argument*s for a non-type *template-parameter* of type
253
- “pointer to int.”
254
  - For a non-type *template-parameter* of type reference to object, no
255
  conversions apply. The type referred to by the reference may be more
256
  cv-qualified than the (otherwise identical) type of the
257
  *template-argument*. The *template-parameter* is bound directly to the
258
  *template-argument*, which shall be an lvalue.
@@ -308,15 +309,15 @@ only primary class templates are considered when matching the template
308
  template argument with the corresponding parameter; partial
309
  specializations are not considered even if their parameter lists match
310
  that of the template template parameter.
311
 
312
  Any partial specializations ([[temp.class.spec]]) associated with the
313
- primary class template are considered when a specialization based on the
314
- template *template-parameter* is instantiated. If a specialization is
315
- not visible at the point of instantiation, and it would have been
316
- selected had it been visible, the program is ill-formed; no diagnostic
317
- is required.
318
 
319
  ``` cpp
320
  template<class T> class A { // primary template
321
  int x;
322
  };
@@ -331,10 +332,26 @@ C<A> c; // V<int> within C<A> uses the primary template,
331
  // so c.y.x has type int
332
  // V<int*> within C<A> uses the partial specialization,
333
  // so c.z.x has type long
334
  ```
335
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
336
  ``` cpp
337
  template<class T> class A { /* ... */ };
338
  template<class T, class U = T> class B { /* ... */ };
339
  template <class ... Types> class C { /* ... */ };
340
 
@@ -348,22 +365,10 @@ X<C> xc; // ill-formed: a template parameter pack does not match a te
348
  Y<A> ya; // OK
349
  Y<B> yb; // OK
350
  Y<C> yc; // OK
351
  ```
352
 
353
- A *template-argument* matches a template *template-parameter* (call it
354
- `P`) when each of the template parameters in the
355
- *template-parameter-list* of the *template-argument*’s corresponding
356
- class template or alias template (call it `A`) matches the corresponding
357
- template parameter in the *template-parameter-list* of `P`. When `P`’s
358
- *template-parameter-list* contains a template parameter pack (
359
- [[temp.variadic]]), the template parameter pack will match zero or more
360
- template parameters or template parameter packs in the
361
- *template-parameter-list* of `A` with the same type and form as the
362
- template parameter pack in `P` (ignoring whether those template
363
- parameters are template parameter packs)
364
-
365
  ``` cpp
366
  template <class T> struct eval;
367
 
368
  template <template <class, class...> class TT, class T1, class... Rest>
369
  struct eval<TT<T1, Rest...>> { };
 
172
  - for a non-type *template-parameter* of integral or enumeration type, a
173
  converted constant expression ([[expr.const]]) of the type of the
174
  *template-parameter*; or
175
  - the name of a non-type *template-parameter*; or
176
  - a constant expression ([[expr.const]]) that designates the address of
177
+ a complete object with static storage duration and external or
178
+ internal linkage or a function with external or internal linkage,
179
+ including function templates and function *template-id*s but excluding
180
  non-static class members, expressed (ignoring parentheses) as `&`
181
+ *id-expression*, where the *id-expression* is the name of an object or
182
+ function, except that the `&` may be omitted if the name refers to a
183
+ function or array and shall be omitted if the corresponding
184
  *template-parameter* is a reference; or
185
  - a constant expression that evaluates to a null pointer value (
186
  [[conv.ptr]]); or
187
  - a constant expression that evaluates to a null member pointer value (
188
  [[conv.mem]]); or
189
+ - a pointer to member expressed as described in  [[expr.unary.op]]; or
190
+ - a constant expression of type `std::nullptr_t`.
191
 
192
  A string literal ([[lex.string]]) does not satisfy the requirements of
193
  any of these categories and thus is not an acceptable
194
  *template-argument*.
195
 
 
243
  - for a non-type *template-parameter* of type pointer to object,
244
  qualification conversions ([[conv.qual]]) and the array-to-pointer
245
  conversion ([[conv.array]]) are applied; if the *template-argument*
246
  is of type `std::nullptr_t`, the null pointer conversion (
247
  [[conv.ptr]]) is applied. In particular, neither the null pointer
248
+ conversion for a zero-valued integer literal ([[conv.ptr]]) nor the
249
+ derived-to-base conversion ([[conv.ptr]]) are applied. Although `0`
250
+ is a valid *template-argument* for a non-type *template-parameter* of
251
+ integral type, it is not a valid *template-argument* for a non-type
252
+ *template-parameter* of pointer type. However, both `(int*)0` and
253
+ `nullptr` are valid *template-argument*s for a non-type
254
+ *template-parameter* of type “pointer to int.”
 
255
  - For a non-type *template-parameter* of type reference to object, no
256
  conversions apply. The type referred to by the reference may be more
257
  cv-qualified than the (otherwise identical) type of the
258
  *template-argument*. The *template-parameter* is bound directly to the
259
  *template-argument*, which shall be an lvalue.
 
309
  template argument with the corresponding parameter; partial
310
  specializations are not considered even if their parameter lists match
311
  that of the template template parameter.
312
 
313
  Any partial specializations ([[temp.class.spec]]) associated with the
314
+ primary class template or primary variable template are considered when
315
+ a specialization based on the template *template-parameter* is
316
+ instantiated. If a specialization is not visible at the point of
317
+ instantiation, and it would have been selected had it been visible, the
318
+ program is ill-formed; no diagnostic is required.
319
 
320
  ``` cpp
321
  template<class T> class A { // primary template
322
  int x;
323
  };
 
332
  // so c.y.x has type int
333
  // V<int*> within C<A> uses the partial specialization,
334
  // so c.z.x has type long
335
  ```
336
 
337
+ A *template-argument* matches a template *template-parameter* (call it
338
+ `P`) when each of the template parameters in the
339
+ *template-parameter-list* of the *template-argument*’s corresponding
340
+ class template or alias template (call it `A`) matches the corresponding
341
+ template parameter in the *template-parameter-list* of `P`. Two template
342
+ parameters match if they are of the same kind (type, non-type,
343
+ template), for non-type *template-parameter*s, their types are
344
+ equivalent ([[temp.over.link]]), and for template
345
+ *template-parameter*s, each of their corresponding *template-parameter*s
346
+ matches, recursively. When `P`’s *template-parameter-list* contains a
347
+ template parameter pack ([[temp.variadic]]), the template parameter
348
+ pack will match zero or more template parameters or template parameter
349
+ packs in the *template-parameter-list* of `A` with the same type and
350
+ form as the template parameter pack in `P` (ignoring whether those
351
+ template parameters are template parameter packs).
352
+
353
  ``` cpp
354
  template<class T> class A { /* ... */ };
355
  template<class T, class U = T> class B { /* ... */ };
356
  template <class ... Types> class C { /* ... */ };
357
 
 
365
  Y<A> ya; // OK
366
  Y<B> yb; // OK
367
  Y<C> yc; // OK
368
  ```
369
 
 
 
 
 
 
 
 
 
 
 
 
 
370
  ``` cpp
371
  template <class T> struct eval;
372
 
373
  template <template <class, class...> class TT, class T1, class... Rest>
374
  struct eval<TT<T1, Rest...>> { };