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
|
|
|
|
|
|
|
| 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;
|
| 30 |
-
|
| 31 |
-
// V<int*> within C<A> uses the partial specialization,
|
| 32 |
-
// so c.z.x has type long
|
| 33 |
```
|
| 34 |
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
*template-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
parameters
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
*template-parameter*s,
|
| 44 |
-
|
| 45 |
-
template
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
template
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
|
| 51 |
``` cpp
|
| 52 |
-
template<class T> class A {
|
| 53 |
-
template<class T, class U = T> class B {
|
| 54 |
-
template
|
| 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; //
|
| 61 |
-
X<C> xc; //
|
| 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 |
+
|