From Jason Turner

[temp.arg.template]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpbcgk5h9g/{from.md → to.md} +62 -29
tmp/tmpbcgk5h9g/{from.md → to.md} RENAMED
@@ -11,11 +11,13 @@ that of the template template parameter.
11
  Any partial specializations ([[temp.class.spec]]) associated with the
12
  primary class template or primary variable template are considered when
13
  a specialization based on the template *template-parameter* is
14
  instantiated. If a specialization is not visible at the point of
15
  instantiation, and it would have been selected had it been visible, the
16
- program is ill-formed; no diagnostic is required.
 
 
17
 
18
  ``` cpp
19
  template<class T> class A { // primary template
20
  int x;
21
  };
@@ -24,49 +26,56 @@ template<class T> class A<T*> { // partial specialization
24
  };
25
  template<template<class U> class V> class C {
26
  V<int> y;
27
  V<int*> z;
28
  };
29
- C<A> c; // V<int> within C<A> uses the primary template,
30
- // so c.y.x has type int
31
- // V<int*> within C<A> uses the partial specialization,
32
- // so c.z.x has type long
33
  ```
34
 
35
- A *template-argument* matches a template *template-parameter* (call it
36
- `P`) when each of the template parameters in the
37
- *template-parameter-list* of the *template-argument*’s corresponding
38
- class template or alias template (call it `A`) matches the corresponding
39
- template parameter in the *template-parameter-list* of `P`. Two template
40
- parameters match if they are of the same kind (type, non-type,
41
- template), for non-type *template-parameter*s, their types are
42
- equivalent ([[temp.over.link]]), and for template
43
- *template-parameter*s, each of their corresponding *template-parameter*s
44
- matches, recursively. When `P`’s *template-parameter-list* contains a
45
- template parameter pack ([[temp.variadic]]), the template parameter
46
- pack will match zero or more template parameters or template parameter
47
- packs in the *template-parameter-list* of `A` with the same type and
48
- form as the template parameter pack in `P` (ignoring whether those
49
- template parameters are template parameter packs).
 
 
 
 
50
 
51
  ``` cpp
52
- template<class T> class A { /* ... */ };
53
- template<class T, class U = T> class B { /* ... */ };
54
- template <class ... Types> class C { /* ... */ };
55
-
56
- template<template<class> class P> class X { /* ... */ };
57
- template<template<class ...> class Q> class Y { /* ... */ };
 
58
 
59
  X<A> xa; // OK
60
- X<B> xb; // ill-formed: default arguments for the parameters of a template argument are ignored
61
- X<C> xc; // ill-formed: a template parameter pack does not match a template parameter
62
-
63
  Y<A> ya; // OK
64
  Y<B> yb; // OK
65
  Y<C> yc; // OK
 
66
  ```
67
 
 
 
 
 
68
  ``` cpp
69
  template <class T> struct eval;
70
 
71
  template <template <class, class...> class TT, class T1, class... Rest>
72
  struct eval<TT<T1, Rest...>> { };
@@ -82,5 +91,29 @@ eval<B<int, float>> eB; // OK: matches partial specialization of eval
82
  eval<C<17>> eC; // error: C does not match TT in partial specialization
83
  eval<D<int, 17>> eD; // error: D does not match TT in partial specialization
84
  eval<E<int, float>> eE; // error: E does not match TT in partial specialization
85
  ```
86
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  Any partial specializations ([[temp.class.spec]]) associated with the
12
  primary class template or primary variable template are considered when
13
  a specialization based on the template *template-parameter* is
14
  instantiated. If a specialization is not visible at the point of
15
  instantiation, and it would have been selected had it been visible, the
16
+ program is ill-formed, no diagnostic required.
17
+
18
+ [*Example 1*:
19
 
20
  ``` cpp
21
  template<class T> class A { // primary template
22
  int x;
23
  };
 
26
  };
27
  template<template<class U> class V> class C {
28
  V<int> y;
29
  V<int*> z;
30
  };
31
+ C<A> c; // V<int> within C<A> uses the primary template, so c.y.x has type int
32
+ // V<int*> within C<A> uses the partial specialization, so c.z.x has type long
 
 
33
  ```
34
 
35
+ *end example*]
36
+
37
+ A *template-argument* matches a template *template-parameter* `P` when
38
+ `P` is at least as specialized as the *template-argument* `A`. If `P`
39
+ contains a parameter pack, then `A` also matches `P` if each of `A`’s
40
+ template parameters matches the corresponding template parameter in the
41
+ *template-parameter-list* of `P`. Two template parameters match if they
42
+ are of the same kind (type, non-type, template), for non-type
43
+ *template-parameter*s, their types are equivalent ([[temp.over.link]]),
44
+ and for template *template-parameter*s, each of their corresponding
45
+ *template-parameter*s matches, recursively. When `P`’s
46
+ *template-parameter-list* contains a template parameter pack (
47
+ [[temp.variadic]]), the template parameter pack will match zero or more
48
+ template parameters or template parameter packs in the
49
+ *template-parameter-list* of `A` with the same type and form as the
50
+ template parameter pack in `P` (ignoring whether those template
51
+ parameters are template parameter packs).
52
+
53
+ [*Example 2*:
54
 
55
  ``` cpp
56
+ template<class T> class A { ... };
57
+ template<class T, class U = T> class B { ... };
58
+ template<class ... Types> class C { ... };
59
+ template<auto n> class D { ... };
60
+ template<template<class> class P> class X { ... };
61
+ template<template<class ...> class Q> class Y { ... };
62
+ template<template<int> class R> class Z { ... };
63
 
64
  X<A> xa; // OK
65
+ X<B> xb; // OK
66
+ X<C> xc; // OK
 
67
  Y<A> ya; // OK
68
  Y<B> yb; // OK
69
  Y<C> yc; // OK
70
+ Z<D> zd; // OK
71
  ```
72
 
73
+ — *end example*]
74
+
75
+ [*Example 3*:
76
+
77
  ``` cpp
78
  template <class T> struct eval;
79
 
80
  template <template <class, class...> class TT, class T1, class... Rest>
81
  struct eval<TT<T1, Rest...>> { };
 
91
  eval<C<17>> eC; // error: C does not match TT in partial specialization
92
  eval<D<int, 17>> eD; // error: D does not match TT in partial specialization
93
  eval<E<int, float>> eE; // error: E does not match TT in partial specialization
94
  ```
95
 
96
+ — *end example*]
97
+
98
+ A template *template-parameter* `P` is at least as specialized as a
99
+ template *template-argument* `A` if, given the following rewrite to two
100
+ function templates, the function template corresponding to `P` is at
101
+ least as specialized as the function template corresponding to `A`
102
+ according to the partial ordering rules for function templates (
103
+ [[temp.func.order]]). Given an invented class template `X` with the
104
+ template parameter list of `A` (including default arguments):
105
+
106
+ - Each of the two function templates has the same template parameters,
107
+ respectively, as `P` or `A`.
108
+ - Each function template has a single function parameter whose type is a
109
+ specialization of `X` with template arguments corresponding to the
110
+ template parameters from the respective function template where, for
111
+ each template parameter `PP` in the template parameter list of the
112
+ function template, a corresponding template argument `AA` is formed.
113
+ If `PP` declares a parameter pack, then `AA` is the pack expansion
114
+ `PP...` ([[temp.variadic]]); otherwise, `AA` is the *id-expression*
115
+ `PP`.
116
+
117
+ If the rewrite produces an invalid type, then `P` is not at least as
118
+ specialized as `A`.
119
+