tmp/tmpny0uun8p/{from.md → to.md}
RENAMED
|
@@ -28,28 +28,34 @@ template-argument-list:
|
|
| 28 |
|
| 29 |
``` bnf
|
| 30 |
template-argument:
|
| 31 |
constant-expression
|
| 32 |
type-id
|
| 33 |
-
|
|
|
|
|
|
|
| 34 |
```
|
| 35 |
|
| 36 |
The component name of a *simple-template-id*, *template-id*, or
|
| 37 |
*template-name* is the first name in it.
|
| 38 |
|
| 39 |
A `<` is interpreted as the delimiter of a *template-argument-list* if
|
| 40 |
-
|
| 41 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
- that follows the keyword `template` or a `~` after a
|
| 43 |
*nested-name-specifier* or in a class member access expression, or
|
| 44 |
- for which name lookup finds the injected-class-name of a class
|
| 45 |
template or finds any declaration of a template, or
|
| 46 |
-
- that is an unqualified name for which name lookup either finds one
|
| 47 |
-
|
| 48 |
- that is a terminal name in a *using-declarator* [[namespace.udecl]],
|
| 49 |
-
|
| 50 |
-
|
| 51 |
|
| 52 |
[*Note 1*: If the name is an *identifier*, it is then interpreted as a
|
| 53 |
*template-name*. The keyword `template` is used to indicate that a
|
| 54 |
dependent qualified name [[temp.dep.type]] denotes a template where an
|
| 55 |
expression might appear. — *end note*]
|
|
@@ -64,24 +70,30 @@ struct X {
|
|
| 64 |
template<class T> void f(T* p) {
|
| 65 |
T* p1 = p->alloc<200>(); // error: < means less than
|
| 66 |
T* p2 = p->template alloc<200>(); // OK, < starts template argument list
|
| 67 |
T::adjust<100>(); // error: < means less than
|
| 68 |
T::template adjust<100>(); // OK, < starts template argument list
|
| 69 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 70 |
```
|
| 71 |
|
| 72 |
— *end example*]
|
| 73 |
|
| 74 |
-
When parsing a *template-argument-list*, the first non-nested `>`[^
|
| 75 |
|
| 76 |
is taken as the ending delimiter rather than a greater-than operator.
|
| 77 |
Similarly, the first non-nested `>>` is treated as two consecutive but
|
| 78 |
distinct `>` tokens, the first of which is taken as the end of the
|
| 79 |
-
*template-argument-list* and completes the *template-id*
|
|
|
|
| 80 |
|
| 81 |
[*Note 2*: The second `>` token produced by this replacement rule can
|
| 82 |
-
terminate an enclosing *template-id*
|
|
|
|
| 83 |
different construct (e.g., a cast). — *end note*]
|
| 84 |
|
| 85 |
[*Example 2*:
|
| 86 |
|
| 87 |
``` cpp
|
|
@@ -99,24 +111,40 @@ Y<X<(6>>1)>> x5; // OK
|
|
| 99 |
— *end example*]
|
| 100 |
|
| 101 |
The keyword `template` shall not appear immediately after a declarative
|
| 102 |
*nested-name-specifier* [[expr.prim.id.qual]].
|
| 103 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 104 |
A name prefixed by the keyword `template` shall be followed by a
|
| 105 |
template argument list or refer to a class template or an alias
|
| 106 |
template. The latter case is deprecated [[depr.template.template]]. The
|
| 107 |
keyword `template` shall not appear immediately before a `~` token (as
|
| 108 |
to name a destructor).
|
| 109 |
|
| 110 |
[*Note 3*: The keyword `template` cannot be applied to non-template
|
| 111 |
members of class templates. — *end note*]
|
| 112 |
|
| 113 |
[*Note 4*: As is the case with the `typename` prefix, the `template`
|
| 114 |
-
prefix is
|
| 115 |
template. — *end note*]
|
| 116 |
|
| 117 |
-
[*Example
|
| 118 |
|
| 119 |
``` cpp
|
| 120 |
template <class T> struct A {
|
| 121 |
void f(int);
|
| 122 |
template <class U> void f(U);
|
|
@@ -137,27 +165,29 @@ template <class T, template <class X> class TT = T::template C> struct D { };
|
|
| 137 |
D<B<int> > db;
|
| 138 |
```
|
| 139 |
|
| 140 |
— *end example*]
|
| 141 |
|
| 142 |
-
A *template-id* is *valid* if
|
| 143 |
|
| 144 |
- there are at most as many arguments as there are parameters or a
|
| 145 |
parameter is a template parameter pack [[temp.variadic]],
|
| 146 |
- there is an argument for each non-deducible non-pack parameter that
|
| 147 |
does not have a default *template-argument*,
|
| 148 |
-
- each *template-argument* matches the corresponding
|
| 149 |
-
|
| 150 |
- substitution of each template argument into the following template
|
| 151 |
parameters (if any) succeeds, and
|
| 152 |
-
- if the *template-id*
|
| 153 |
-
|
|
|
|
| 154 |
|
| 155 |
-
A *simple-template-id*
|
| 156 |
-
template
|
|
|
|
| 157 |
|
| 158 |
-
[*Example
|
| 159 |
|
| 160 |
``` cpp
|
| 161 |
template<class T, T::type n = 0> class X;
|
| 162 |
struct S {
|
| 163 |
using type = int;
|
|
@@ -169,18 +199,19 @@ using T4 = X<int>; // error: substitution failure for second templa
|
|
| 169 |
using T5 = X<S>; // OK
|
| 170 |
```
|
| 171 |
|
| 172 |
— *end example*]
|
| 173 |
|
| 174 |
-
When the *template-name* of a *simple-template-id*
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
[[temp.
|
| 179 |
-
[[temp.constr.
|
|
|
|
| 180 |
|
| 181 |
-
[*Example
|
| 182 |
|
| 183 |
``` cpp
|
| 184 |
template<typename T> concept C1 = sizeof(T) != sizeof(int);
|
| 185 |
|
| 186 |
template<C1 T> struct S1 { };
|
|
@@ -222,11 +253,11 @@ satisfied [[temp.constr.constr]] by the specified template arguments and
|
|
| 222 |
[*Note 5*: Since a *constraint-expression* is an unevaluated operand, a
|
| 223 |
concept-id appearing in a *constraint-expression* is not evaluated
|
| 224 |
except as necessary to determine whether the normalized constraints are
|
| 225 |
satisfied. — *end note*]
|
| 226 |
|
| 227 |
-
[*Example
|
| 228 |
|
| 229 |
``` cpp
|
| 230 |
template<typename T> concept C = true;
|
| 231 |
static_assert(C<int>); // OK
|
| 232 |
```
|
|
|
|
| 28 |
|
| 29 |
``` bnf
|
| 30 |
template-argument:
|
| 31 |
constant-expression
|
| 32 |
type-id
|
| 33 |
+
nested-name-specifierₒₚₜ template-name
|
| 34 |
+
nested-name-specifier 'template' template-name
|
| 35 |
+
braced-init-list
|
| 36 |
```
|
| 37 |
|
| 38 |
The component name of a *simple-template-id*, *template-id*, or
|
| 39 |
*template-name* is the first name in it.
|
| 40 |
|
| 41 |
A `<` is interpreted as the delimiter of a *template-argument-list* if
|
| 42 |
+
either
|
| 43 |
|
| 44 |
+
- it follows a *splice-specifier* that either
|
| 45 |
+
- appears in a type-only context or
|
| 46 |
+
- is preceded by `template` or `typename`, or
|
| 47 |
+
- it follows a name that is not a *conversion-function-id* and
|
| 48 |
- that follows the keyword `template` or a `~` after a
|
| 49 |
*nested-name-specifier* or in a class member access expression, or
|
| 50 |
- for which name lookup finds the injected-class-name of a class
|
| 51 |
template or finds any declaration of a template, or
|
| 52 |
+
- that is an unqualified name for which name lookup either finds one
|
| 53 |
+
or more functions or finds nothing, or
|
| 54 |
- that is a terminal name in a *using-declarator* [[namespace.udecl]],
|
| 55 |
+
in a *declarator-id* [[dcl.meaning]], or in a type-only context
|
| 56 |
+
other than a *nested-name-specifier* [[temp.res]].
|
| 57 |
|
| 58 |
[*Note 1*: If the name is an *identifier*, it is then interpreted as a
|
| 59 |
*template-name*. The keyword `template` is used to indicate that a
|
| 60 |
dependent qualified name [[temp.dep.type]] denotes a template where an
|
| 61 |
expression might appear. — *end note*]
|
|
|
|
| 70 |
template<class T> void f(T* p) {
|
| 71 |
T* p1 = p->alloc<200>(); // error: < means less than
|
| 72 |
T* p2 = p->template alloc<200>(); // OK, < starts template argument list
|
| 73 |
T::adjust<100>(); // error: < means less than
|
| 74 |
T::template adjust<100>(); // OK, < starts template argument list
|
| 75 |
+
|
| 76 |
+
static constexpr std::meta::info r = ^^T::adjust;
|
| 77 |
+
T* p3 = [:r:]<200>(); // error: < means less than
|
| 78 |
+
T* p4 = template [:r:]<200>(); // OK, < starts template argument list
|
| 79 |
+
}}
|
| 80 |
```
|
| 81 |
|
| 82 |
— *end example*]
|
| 83 |
|
| 84 |
+
When parsing a *template-argument-list*, the first non-nested `>`[^1]
|
| 85 |
|
| 86 |
is taken as the ending delimiter rather than a greater-than operator.
|
| 87 |
Similarly, the first non-nested `>>` is treated as two consecutive but
|
| 88 |
distinct `>` tokens, the first of which is taken as the end of the
|
| 89 |
+
*template-argument-list* and completes the *template-id* or
|
| 90 |
+
*splice-specialization-specifier*.
|
| 91 |
|
| 92 |
[*Note 2*: The second `>` token produced by this replacement rule can
|
| 93 |
+
terminate an enclosing *template-id* or
|
| 94 |
+
*splice-specialization-specifier* construct or it can be part of a
|
| 95 |
different construct (e.g., a cast). — *end note*]
|
| 96 |
|
| 97 |
[*Example 2*:
|
| 98 |
|
| 99 |
``` cpp
|
|
|
|
| 111 |
— *end example*]
|
| 112 |
|
| 113 |
The keyword `template` shall not appear immediately after a declarative
|
| 114 |
*nested-name-specifier* [[expr.prim.id.qual]].
|
| 115 |
|
| 116 |
+
The *constant-expression* of a *template-argument* shall not be an
|
| 117 |
+
unparenthesized *splice-expression*.
|
| 118 |
+
|
| 119 |
+
[*Example 3*:
|
| 120 |
+
|
| 121 |
+
``` cpp
|
| 122 |
+
template<int> struct S { };
|
| 123 |
+
constexpr int k = 5;
|
| 124 |
+
constexpr std::meta::info r = ^^k;
|
| 125 |
+
S<[:r:]> s1; // error: unparenthesized splice-expression used as template argument
|
| 126 |
+
S<([:r:])> s2; // OK
|
| 127 |
+
S<[:r:] + 1> s3; // OK
|
| 128 |
+
```
|
| 129 |
+
|
| 130 |
+
— *end example*]
|
| 131 |
+
|
| 132 |
A name prefixed by the keyword `template` shall be followed by a
|
| 133 |
template argument list or refer to a class template or an alias
|
| 134 |
template. The latter case is deprecated [[depr.template.template]]. The
|
| 135 |
keyword `template` shall not appear immediately before a `~` token (as
|
| 136 |
to name a destructor).
|
| 137 |
|
| 138 |
[*Note 3*: The keyword `template` cannot be applied to non-template
|
| 139 |
members of class templates. — *end note*]
|
| 140 |
|
| 141 |
[*Note 4*: As is the case with the `typename` prefix, the `template`
|
| 142 |
+
prefix is well-formed even when lookup for the name would already find a
|
| 143 |
template. — *end note*]
|
| 144 |
|
| 145 |
+
[*Example 4*:
|
| 146 |
|
| 147 |
``` cpp
|
| 148 |
template <class T> struct A {
|
| 149 |
void f(int);
|
| 150 |
template <class U> void f(U);
|
|
|
|
| 165 |
D<B<int> > db;
|
| 166 |
```
|
| 167 |
|
| 168 |
— *end example*]
|
| 169 |
|
| 170 |
+
A *template-id* or *splice-specialization-specifier* is *valid* if
|
| 171 |
|
| 172 |
- there are at most as many arguments as there are parameters or a
|
| 173 |
parameter is a template parameter pack [[temp.variadic]],
|
| 174 |
- there is an argument for each non-deducible non-pack parameter that
|
| 175 |
does not have a default *template-argument*,
|
| 176 |
+
- each *template-argument* matches the corresponding template parameter
|
| 177 |
+
[[temp.arg]],
|
| 178 |
- substitution of each template argument into the following template
|
| 179 |
parameters (if any) succeeds, and
|
| 180 |
+
- if the *template-id* or *splice-specialization-specifier* is
|
| 181 |
+
non-dependent, the associated constraints are satisfied as specified
|
| 182 |
+
in the next paragraph.
|
| 183 |
|
| 184 |
+
A *simple-template-id* or *splice-specialization-specifier* shall be
|
| 185 |
+
valid unless its respective *template-name* or *splice-specifier* names
|
| 186 |
+
or designates a function template [[temp.deduct]].
|
| 187 |
|
| 188 |
+
[*Example 5*:
|
| 189 |
|
| 190 |
``` cpp
|
| 191 |
template<class T, T::type n = 0> class X;
|
| 192 |
struct S {
|
| 193 |
using type = int;
|
|
|
|
| 199 |
using T5 = X<S>; // OK
|
| 200 |
```
|
| 201 |
|
| 202 |
— *end example*]
|
| 203 |
|
| 204 |
+
When the *template-name* of a *simple-template-id* or the
|
| 205 |
+
*splice-specifier* of a *splice-specialization-specifier* designates a
|
| 206 |
+
constrained non-function template or a constrained template template
|
| 207 |
+
parameter, and all *template-argument*s in the *simple-template-id* or
|
| 208 |
+
*splice-specialization-specifier* are non-dependent [[temp.dep.temp]],
|
| 209 |
+
the associated constraints [[temp.constr.decl]] of the constrained
|
| 210 |
+
template shall be satisfied [[temp.constr.constr]].
|
| 211 |
|
| 212 |
+
[*Example 6*:
|
| 213 |
|
| 214 |
``` cpp
|
| 215 |
template<typename T> concept C1 = sizeof(T) != sizeof(int);
|
| 216 |
|
| 217 |
template<C1 T> struct S1 { };
|
|
|
|
| 253 |
[*Note 5*: Since a *constraint-expression* is an unevaluated operand, a
|
| 254 |
concept-id appearing in a *constraint-expression* is not evaluated
|
| 255 |
except as necessary to determine whether the normalized constraints are
|
| 256 |
satisfied. — *end note*]
|
| 257 |
|
| 258 |
+
[*Example 7*:
|
| 259 |
|
| 260 |
``` cpp
|
| 261 |
template<typename T> concept C = true;
|
| 262 |
static_assert(C<int>); // OK
|
| 263 |
```
|