From Jason Turner

[temp.names]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. 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 ([[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,32 +31,39 @@ template-argument:
31
  constant-expression
32
  type-id
33
  id-expression
34
  ```
35
 
36
- [*Note 1*: The name lookup rules ([[basic.lookup]]) are used to
37
- associate the use of a name with a template declaration; that is, to
38
- identify a 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 known to refer to a template.
42
-
43
- After name lookup ([[basic.lookup]]) finds that a name is a
44
- *template-name* or that an *operator-function-id* or a
45
- *literal-operator-id* refers to a set of overloaded functions any member
46
- of which is a function template, if this is followed by a `<`, the `<`
47
- is always taken as the delimiter of a *template-argument-list* and never
48
- as the less-than operator. When parsing a *template-argument-list*, the
49
- first non-nested `>`[^2] is taken as the ending delimiter rather than a
50
- greater-than operator. Similarly, the first non-nested `>{>}` is treated
51
- as two consecutive but distinct `>` tokens, the first of which is taken
52
- as the end of the *template-argument-list* and completes the
53
- *template-id*.
54
-
55
- [*Note 2*: The second `>` token produced by this replacement rule may
 
 
 
 
 
 
 
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* (Clause  [[class]]) or
79
- *enum-head-name* ([[dcl.enum]]), the keyword `template` shall not
80
- appear at the top level. In a *qualified-id* used as the name in a
81
- *typename-specifier* ([[temp.res]]), *elaborated-type-specifier* (
82
- [[dcl.type.elab]]), *using-declaration* ([[namespace.udecl]]), or
83
- *class-or-decltype* (Clause  [[class.derived]]), an optional keyword
84
- `template` appearing at the top level is ignored. In these contexts, a
85
- `<` token is always assumed to introduce a *template-argument-list*. In
86
- all other contexts, when naming a template specialization of a member of
87
- an unknown specialization ([[temp.dep.type]]), the member template name
88
- shall be prefixed by the keyword `template`.
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>(); // ill-formed: < means less than
99
  T* p2 = p->template alloc<200>(); // OK: < starts template argument list
100
- T::adjust<100>(); // ill-formed: < means less than
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 3*: The keyword `template` may not 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 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 *simple-template-id* that names a class template specialization is a
145
- *class-name* (Clause  [[class]]).
146
 
147
- A *template-id* that names an alias template specialization is a
148
- *type-name*.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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