- tmp/tmplzno9kbo/{from.md → to.md} +135 -39
tmp/tmplzno9kbo/{from.md → to.md}
RENAMED
|
@@ -1,8 +1,8 @@
|
|
| 1 |
## Names of template specializations <a id="temp.names">[[temp.names]]</a>
|
| 2 |
|
| 3 |
-
A template specialization
|
| 4 |
*template-id*:
|
| 5 |
|
| 6 |
``` bnf
|
| 7 |
simple-template-id:
|
| 8 |
template-name '<' template-argument-listₒₚₜ '>'
|
|
@@ -31,32 +31,39 @@ template-argument:
|
|
| 31 |
constant-expression
|
| 32 |
type-id
|
| 33 |
id-expression
|
| 34 |
```
|
| 35 |
|
| 36 |
-
[*Note 1*: The name lookup rules
|
| 37 |
-
|
| 38 |
-
|
| 39 |
|
| 40 |
For a *template-name* to be explicitly qualified by the template
|
| 41 |
-
arguments, the name must be
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
*template-
|
| 54 |
-
|
| 55 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
terminate an enclosing *template-id* construct or it may be part of a
|
| 57 |
-
different construct (e.g. a cast). — *end note*]
|
| 58 |
|
| 59 |
[*Example 1*:
|
| 60 |
|
| 61 |
``` cpp
|
| 62 |
template<int i> class X { ... };
|
|
@@ -73,46 +80,46 @@ Y<X<(6>>1)>> x5; // OK
|
|
| 73 |
— *end example*]
|
| 74 |
|
| 75 |
The keyword `template` is said to appear at the top level in a
|
| 76 |
*qualified-id* if it appears outside of a *template-argument-list* or
|
| 77 |
*decltype-specifier*. In a *qualified-id* of a *declarator-id* or in a
|
| 78 |
-
*qualified-id* formed by a *class-head-name*
|
| 79 |
-
*enum-head-name*
|
| 80 |
-
|
| 81 |
-
*typename-specifier*
|
| 82 |
-
[[dcl.type.elab]]
|
| 83 |
-
*class-or-decltype*
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
|
| 90 |
[*Example 2*:
|
| 91 |
|
| 92 |
``` cpp
|
| 93 |
struct X {
|
| 94 |
template<std::size_t> X* alloc();
|
| 95 |
template<std::size_t> static X* adjust();
|
| 96 |
};
|
| 97 |
template<class T> void f(T* p) {
|
| 98 |
-
T* p1 = p->alloc<200>(); //
|
| 99 |
T* p2 = p->template alloc<200>(); // OK: < starts template argument list
|
| 100 |
-
T::adjust<100>(); //
|
| 101 |
T::template adjust<100>(); // OK: < starts template argument list
|
| 102 |
}
|
| 103 |
```
|
| 104 |
|
| 105 |
— *end example*]
|
| 106 |
|
| 107 |
A name prefixed by the keyword `template` shall be a *template-id* or
|
| 108 |
the name shall refer to a class template or an alias template.
|
| 109 |
|
| 110 |
-
[*Note
|
| 111 |
members of class templates. — *end note*]
|
| 112 |
|
| 113 |
-
[*Note
|
| 114 |
prefix is allowed in cases where it is not strictly necessary; i.e.,
|
| 115 |
when the *nested-name-specifier* or the expression on the left of the
|
| 116 |
`->` or `.` is not dependent on a *template-parameter*, or the use does
|
| 117 |
not appear in the scope of a template. — *end note*]
|
| 118 |
|
|
@@ -139,11 +146,100 @@ template <class T, template <class X> class TT = T::template C> struct D { };
|
|
| 139 |
D<B<int> > db;
|
| 140 |
```
|
| 141 |
|
| 142 |
— *end example*]
|
| 143 |
|
| 144 |
-
A *
|
| 145 |
-
*class-name* (Clause [[class]]).
|
| 146 |
|
| 147 |
-
|
| 148 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 149 |
|
|
|
|
| 1 |
## Names of template specializations <a id="temp.names">[[temp.names]]</a>
|
| 2 |
|
| 3 |
+
A template specialization [[temp.spec]] can be referred to by a
|
| 4 |
*template-id*:
|
| 5 |
|
| 6 |
``` bnf
|
| 7 |
simple-template-id:
|
| 8 |
template-name '<' template-argument-listₒₚₜ '>'
|
|
|
|
| 31 |
constant-expression
|
| 32 |
type-id
|
| 33 |
id-expression
|
| 34 |
```
|
| 35 |
|
| 36 |
+
[*Note 1*: The name lookup rules [[basic.lookup]] are used to associate
|
| 37 |
+
the use of a name with a template declaration; that is, to identify a
|
| 38 |
+
name as a *template-name*. — *end note*]
|
| 39 |
|
| 40 |
For a *template-name* to be explicitly qualified by the template
|
| 41 |
+
arguments, the name must be considered to refer to a template.
|
| 42 |
+
|
| 43 |
+
[*Note 2*: Whether a name actually refers to a template cannot be known
|
| 44 |
+
in some cases until after argument dependent lookup is done
|
| 45 |
+
[[basic.lookup.argdep]]. — *end note*]
|
| 46 |
+
|
| 47 |
+
A name is considered to refer to a template if name lookup finds a
|
| 48 |
+
*template-name* or an overload set that contains a function template. A
|
| 49 |
+
name is also considered to refer to a template if it is an
|
| 50 |
+
*unqualified-id* followed by a `<` and name lookup either finds one or
|
| 51 |
+
more functions or finds nothing.
|
| 52 |
+
|
| 53 |
+
When a name is considered to be a *template-name*, and it is followed by
|
| 54 |
+
a `<`, the `<` is always taken as the delimiter of a
|
| 55 |
+
*template-argument-list* and never as the less-than operator. When
|
| 56 |
+
parsing a *template-argument-list*, the first non-nested `>`[^2] is
|
| 57 |
+
taken as the ending delimiter rather than a greater-than operator.
|
| 58 |
+
Similarly, the first non-nested `>{>}` is treated as two consecutive but
|
| 59 |
+
distinct `>` tokens, the first of which is taken as the end of the
|
| 60 |
+
*template-argument-list* and completes the *template-id*.
|
| 61 |
+
|
| 62 |
+
[*Note 3*: The second `>` token produced by this replacement rule may
|
| 63 |
terminate an enclosing *template-id* construct or it may be part of a
|
| 64 |
+
different construct (e.g., a cast). — *end note*]
|
| 65 |
|
| 66 |
[*Example 1*:
|
| 67 |
|
| 68 |
``` cpp
|
| 69 |
template<int i> class X { ... };
|
|
|
|
| 80 |
— *end example*]
|
| 81 |
|
| 82 |
The keyword `template` is said to appear at the top level in a
|
| 83 |
*qualified-id* if it appears outside of a *template-argument-list* or
|
| 84 |
*decltype-specifier*. In a *qualified-id* of a *declarator-id* or in a
|
| 85 |
+
*qualified-id* formed by a *class-head-name* [[class.pre]] or
|
| 86 |
+
*enum-head-name* [[dcl.enum]], the keyword `template` shall not appear
|
| 87 |
+
at the top level. In a *qualified-id* used as the name in a
|
| 88 |
+
*typename-specifier* [[temp.res]], *elaborated-type-specifier*
|
| 89 |
+
[[dcl.type.elab]], *using-declaration* [[namespace.udecl]], or
|
| 90 |
+
*class-or-decltype* [[class.derived]], an optional keyword `template`
|
| 91 |
+
appearing at the top level is ignored. In these contexts, a `<` token is
|
| 92 |
+
always assumed to introduce a *template-argument-list*. In all other
|
| 93 |
+
contexts, when naming a template specialization of a member of an
|
| 94 |
+
unknown specialization [[temp.dep.type]], the member template name shall
|
| 95 |
+
be prefixed by the keyword `template`.
|
| 96 |
|
| 97 |
[*Example 2*:
|
| 98 |
|
| 99 |
``` cpp
|
| 100 |
struct X {
|
| 101 |
template<std::size_t> X* alloc();
|
| 102 |
template<std::size_t> static X* adjust();
|
| 103 |
};
|
| 104 |
template<class T> void f(T* p) {
|
| 105 |
+
T* p1 = p->alloc<200>(); // error: < means less than
|
| 106 |
T* p2 = p->template alloc<200>(); // OK: < starts template argument list
|
| 107 |
+
T::adjust<100>(); // error: < means less than
|
| 108 |
T::template adjust<100>(); // OK: < starts template argument list
|
| 109 |
}
|
| 110 |
```
|
| 111 |
|
| 112 |
— *end example*]
|
| 113 |
|
| 114 |
A name prefixed by the keyword `template` shall be a *template-id* or
|
| 115 |
the name shall refer to a class template or an alias template.
|
| 116 |
|
| 117 |
+
[*Note 4*: The keyword `template` may not be applied to non-template
|
| 118 |
members of class templates. — *end note*]
|
| 119 |
|
| 120 |
+
[*Note 5*: As is the case with the `typename` prefix, the `template`
|
| 121 |
prefix is allowed in cases where it is not strictly necessary; i.e.,
|
| 122 |
when the *nested-name-specifier* or the expression on the left of the
|
| 123 |
`->` or `.` is not dependent on a *template-parameter*, or the use does
|
| 124 |
not appear in the scope of a template. — *end note*]
|
| 125 |
|
|
|
|
| 146 |
D<B<int> > db;
|
| 147 |
```
|
| 148 |
|
| 149 |
— *end example*]
|
| 150 |
|
| 151 |
+
A *template-id* is *valid* if
|
|
|
|
| 152 |
|
| 153 |
+
- there are at most as many arguments as there are parameters or a
|
| 154 |
+
parameter is a template parameter pack [[temp.variadic]],
|
| 155 |
+
- there is an argument for each non-deducible non-pack parameter that
|
| 156 |
+
does not have a default *template-argument*,
|
| 157 |
+
- each *template-argument* matches the corresponding
|
| 158 |
+
*template-parameter* [[temp.arg]],
|
| 159 |
+
- substitution of each template argument into the following template
|
| 160 |
+
parameters (if any) succeeds, and
|
| 161 |
+
- if the *template-id* is non-dependent, the associated constraints are
|
| 162 |
+
satisfied as specified in the next paragraph.
|
| 163 |
+
|
| 164 |
+
A *simple-template-id* shall be valid unless it names a function
|
| 165 |
+
template specialization [[temp.deduct]].
|
| 166 |
+
|
| 167 |
+
[*Example 4*:
|
| 168 |
+
|
| 169 |
+
``` cpp
|
| 170 |
+
template<class T, T::type n = 0> class X;
|
| 171 |
+
struct S {
|
| 172 |
+
using type = int;
|
| 173 |
+
};
|
| 174 |
+
using T1 = X<S, int, int>; // error: too many arguments
|
| 175 |
+
using T2 = X<>; // error: no default argument for first template parameter
|
| 176 |
+
using T3 = X<1>; // error: value 1 does not match type-parameter
|
| 177 |
+
using T4 = X<int>; // error: substitution failure for second template parameter
|
| 178 |
+
using T5 = X<S>; // OK
|
| 179 |
+
```
|
| 180 |
+
|
| 181 |
+
— *end example*]
|
| 182 |
+
|
| 183 |
+
When the *template-name* of a *simple-template-id* names a constrained
|
| 184 |
+
non-function template or a constrained template *template-parameter*,
|
| 185 |
+
but not a member template that is a member of an unknown specialization
|
| 186 |
+
[[temp.res]], and all *template-argument*s in the *simple-template-id*
|
| 187 |
+
are non-dependent [[temp.dep.temp]], the associated constraints
|
| 188 |
+
[[temp.constr.decl]] of the constrained template shall be satisfied
|
| 189 |
+
[[temp.constr.constr]].
|
| 190 |
+
|
| 191 |
+
[*Example 5*:
|
| 192 |
+
|
| 193 |
+
``` cpp
|
| 194 |
+
template<typename T> concept C1 = sizeof(T) != sizeof(int);
|
| 195 |
+
|
| 196 |
+
template<C1 T> struct S1 { };
|
| 197 |
+
template<C1 T> using Ptr = T*;
|
| 198 |
+
|
| 199 |
+
S1<int>* p; // error: constraints not satisfied
|
| 200 |
+
Ptr<int> p; // error: constraints not satisfied
|
| 201 |
+
|
| 202 |
+
template<typename T>
|
| 203 |
+
struct S2 { Ptr<int> x; }; // ill-formed, no diagnostic required
|
| 204 |
+
|
| 205 |
+
template<typename T>
|
| 206 |
+
struct S3 { Ptr<T> x; }; // OK, satisfaction is not required
|
| 207 |
+
|
| 208 |
+
S3<int> x; // error: constraints not satisfied
|
| 209 |
+
|
| 210 |
+
template<template<C1 T> class X>
|
| 211 |
+
struct S4 {
|
| 212 |
+
X<int> x; // ill-formed, no diagnostic required
|
| 213 |
+
};
|
| 214 |
+
|
| 215 |
+
template<typename T> concept C2 = sizeof(T) == 1;
|
| 216 |
+
|
| 217 |
+
template<C2 T> struct S { };
|
| 218 |
+
|
| 219 |
+
template struct S<char[2]>; // error: constraints not satisfied
|
| 220 |
+
template<> struct S<char[2]> { }; // error: constraints not satisfied
|
| 221 |
+
```
|
| 222 |
+
|
| 223 |
+
— *end example*]
|
| 224 |
+
|
| 225 |
+
A *concept-id* is a *simple-template-id* where the *template-name* is a
|
| 226 |
+
*concept-name*. A concept-id is a prvalue of type `bool`, and does not
|
| 227 |
+
name a template specialization. A concept-id evaluates to `true` if the
|
| 228 |
+
concept’s normalized *constraint-expression* [[temp.constr.decl]] is
|
| 229 |
+
satisfied [[temp.constr.constr]] by the specified template arguments and
|
| 230 |
+
`false` otherwise.
|
| 231 |
+
|
| 232 |
+
[*Note 6*: Since a *constraint-expression* is an unevaluated operand, a
|
| 233 |
+
concept-id appearing in a *constraint-expression* is not evaluated
|
| 234 |
+
except as necessary to determine whether the normalized constraints are
|
| 235 |
+
satisfied. — *end note*]
|
| 236 |
+
|
| 237 |
+
[*Example 6*:
|
| 238 |
+
|
| 239 |
+
``` cpp
|
| 240 |
+
template<typename T> concept C = true;
|
| 241 |
+
static_assert(C<int>); // OK
|
| 242 |
+
```
|
| 243 |
+
|
| 244 |
+
— *end example*]
|
| 245 |
|