From Jason Turner

[temp.spec.partial]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp5mojn86m/{from.md → to.md} +372 -0
tmp/tmp5mojn86m/{from.md → to.md} RENAMED
@@ -0,0 +1,372 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Partial specialization <a id="temp.spec.partial">[[temp.spec.partial]]</a>
2
+
3
+ #### General <a id="temp.spec.partial.general">[[temp.spec.partial.general]]</a>
4
+
5
+ A partial specialization of a template provides an alternative
6
+ definition of the template that is used instead of the primary
7
+ definition when the arguments in a specialization match those given in
8
+ the partial specialization [[temp.spec.partial.match]]. A declaration of
9
+ the primary template shall precede any partial specialization of that
10
+ template. A partial specialization shall be reachable from any use of a
11
+ template specialization that would make use of the partial
12
+ specialization as the result of an implicit or explicit instantiation;
13
+ no diagnostic is required.
14
+
15
+ Two partial specialization declarations declare the same entity if they
16
+ are partial specializations of the same template and have equivalent
17
+ *template-head*s and template argument lists [[temp.over.link]]. Each
18
+ partial specialization is a distinct template.
19
+
20
+ [*Example 1*:
21
+
22
+ ``` cpp
23
+ template<class T1, class T2, int I> class A { };
24
+ template<class T, int I> class A<T, T*, I> { };
25
+ template<class T1, class T2, int I> class A<T1*, T2, I> { };
26
+ template<class T> class A<int, T*, 5> { };
27
+ template<class T1, class T2, int I> class A<T1, T2*, I> { };
28
+ ```
29
+
30
+ The first declaration declares the primary (unspecialized) class
31
+ template. The second and subsequent declarations declare partial
32
+ specializations of the primary template.
33
+
34
+ — *end example*]
35
+
36
+ A partial specialization may be constrained [[temp.constr]].
37
+
38
+ [*Example 2*:
39
+
40
+ ``` cpp
41
+ template<typename T> concept C = true;
42
+
43
+ template<typename T> struct X { };
44
+ template<typename T> struct X<T*> { }; // #1
45
+ template<C T> struct X<T> { }; // #2
46
+ ```
47
+
48
+ Both partial specializations are more specialized than the primary
49
+ template. \#1 is more specialized because the deduction of its template
50
+ arguments from the template argument list of the class template
51
+ specialization succeeds, while the reverse does not. \#2 is more
52
+ specialized because the template arguments are equivalent, but the
53
+ partial specialization is more constrained [[temp.constr.order]].
54
+
55
+ — *end example*]
56
+
57
+ The template argument list of a partial specialization is the
58
+ *template-argument-list* following the name of the template.
59
+
60
+ A partial specialization may be declared in any scope in which the
61
+ corresponding primary template may be defined
62
+ [[dcl.meaning]], [[class.mem]], [[temp.mem]].
63
+
64
+ [*Example 3*:
65
+
66
+ ``` cpp
67
+ template<class T> struct A {
68
+ struct C {
69
+ template<class T2> struct B { };
70
+ template<class T2> struct B<T2**> { }; // partial specialization #1
71
+ };
72
+ };
73
+
74
+ // partial specialization of A<T>::C::B<T2>
75
+ template<class T> template<class T2>
76
+ struct A<T>::C::B<T2*> { }; // #2
77
+
78
+ A<short>::C::B<int*> absip; // uses partial specialization #2
79
+ ```
80
+
81
+ — *end example*]
82
+
83
+ Partial specialization declarations do not introduce a name. Instead,
84
+ when the primary template name is used, any reachable partial
85
+ specializations of the primary template are also considered.
86
+
87
+ [*Note 1*: One consequence is that a *using-declaration* which refers
88
+ to a class template does not restrict the set of partial specializations
89
+ that are found through the *using-declaration*. — *end note*]
90
+
91
+ [*Example 4*:
92
+
93
+ ``` cpp
94
+ namespace N {
95
+ template<class T1, class T2> class A { }; // primary template
96
+ }
97
+
98
+ using N::A; // refers to the primary template
99
+
100
+ namespace N {
101
+ template<class T> class A<T, T*> { }; // partial specialization
102
+ }
103
+
104
+ A<int,int*> a; // uses the partial specialization, which is found through the using-declaration
105
+ // which refers to the primary template
106
+ ```
107
+
108
+ — *end example*]
109
+
110
+ A non-type argument is non-specialized if it is the name of a non-type
111
+ parameter. All other non-type arguments are specialized.
112
+
113
+ Within the argument list of a partial specialization, the following
114
+ restrictions apply:
115
+
116
+ - The type of a template parameter corresponding to a specialized
117
+ non-type argument shall not be dependent on a parameter of the partial
118
+ specialization.
119
+ \[*Example 5*:
120
+ ``` cpp
121
+ template <class T, T t> struct C {};
122
+ template <class T> struct C<T, 1>; // error
123
+
124
+ template< int X, int (*array_ptr)[X] > class A {};
125
+ int array[5];
126
+ template< int X > class A<X,&array> { }; // error
127
+ ```
128
+
129
+ — *end example*]
130
+ - The partial specialization shall be more specialized than the primary
131
+ template [[temp.spec.partial.order]].
132
+ - The template parameter list of a partial specialization shall not
133
+ contain default template argument values.[^8]
134
+ - An argument shall not contain an unexpanded pack. If an argument is a
135
+ pack expansion [[temp.variadic]], it shall be the last argument in the
136
+ template argument list.
137
+
138
+ The usual access checking rules do not apply to non-dependent names used
139
+ to specify template arguments of the *simple-template-id* of the partial
140
+ specialization.
141
+
142
+ [*Note 2*: The template arguments can be private types or objects that
143
+ would normally not be accessible. Dependent names cannot be checked when
144
+ declaring the partial specialization, but will be checked when
145
+ substituting into the partial specialization. — *end note*]
146
+
147
+ #### Matching of partial specializations <a id="temp.spec.partial.match">[[temp.spec.partial.match]]</a>
148
+
149
+ When a template is used in a context that requires an instantiation of
150
+ the template, it is necessary to determine whether the instantiation is
151
+ to be generated using the primary template or one of the partial
152
+ specializations. This is done by matching the template arguments of the
153
+ template specialization with the template argument lists of the partial
154
+ specializations.
155
+
156
+ - If exactly one matching partial specialization is found, the
157
+ instantiation is generated from that partial specialization.
158
+ - If more than one matching partial specialization is found, the partial
159
+ order rules [[temp.spec.partial.order]] are used to determine whether
160
+ one of the partial specializations is more specialized than the
161
+ others. If such a partial specialization exists, the instantiation is
162
+ generated from that partial specialization; otherwise, the use of the
163
+ template is ambiguous and the program is ill-formed.
164
+ - If no matches are found, the instantiation is generated from the
165
+ primary template.
166
+
167
+ A partial specialization matches a given actual template argument list
168
+ if the template arguments of the partial specialization can be deduced
169
+ from the actual template argument list [[temp.deduct]], and the deduced
170
+ template arguments satisfy the associated constraints of the partial
171
+ specialization, if any [[temp.constr.decl]].
172
+
173
+ [*Example 1*:
174
+
175
+ ``` cpp
176
+ template<class T1, class T2, int I> class A { }; // #1
177
+ template<class T, int I> class A<T, T*, I> { }; // #2
178
+ template<class T1, class T2, int I> class A<T1*, T2, I> { }; // #3
179
+ template<class T> class A<int, T*, 5> { }; // #4
180
+ template<class T1, class T2, int I> class A<T1, T2*, I> { }; // #5
181
+
182
+ A<int, int, 1> a1; // uses #1
183
+ A<int, int*, 1> a2; // uses #2, T is int, I is 1
184
+ A<int, char*, 5> a3; // uses #4, T is char
185
+ A<int, char*, 1> a4; // uses #5, T1 is int, T2 is char, I is 1
186
+ A<int*, int*, 2> a5; // ambiguous: matches #3 and #5
187
+ ```
188
+
189
+ — *end example*]
190
+
191
+ [*Example 2*:
192
+
193
+ ``` cpp
194
+ template<typename T> concept C = requires (T t) { t.f(); };
195
+
196
+ template<typename T> struct S { }; // #1
197
+ template<C T> struct S<T> { }; // #2
198
+
199
+ struct Arg { void f(); };
200
+
201
+ S<int> s1; // uses #1; the constraints of #2 are not satisfied
202
+ S<Arg> s2; // uses #2; both constraints are satisfied but #2 is more specialized
203
+ ```
204
+
205
+ — *end example*]
206
+
207
+ If the template arguments of a partial specialization cannot be deduced
208
+ because of the structure of its *template-parameter-list* and the
209
+ *template-id*, the program is ill-formed.
210
+
211
+ [*Example 3*:
212
+
213
+ ``` cpp
214
+ template <int I, int J> struct A {};
215
+ template <int I> struct A<I+5, I*2> {}; // error
216
+
217
+ template <int I> struct A<I, I> {}; // OK
218
+
219
+ template <int I, int J, int K> struct B {};
220
+ template <int I> struct B<I, I*2, 2> {}; // OK
221
+ ```
222
+
223
+ — *end example*]
224
+
225
+ In a name that refers to a specialization of a class or variable
226
+ template (e.g., `A<int, int, 1>`), the argument list shall match the
227
+ template parameter list of the primary template. The template arguments
228
+ of a partial specialization are deduced from the arguments of the
229
+ primary template.
230
+
231
+ #### Partial ordering of partial specializations <a id="temp.spec.partial.order">[[temp.spec.partial.order]]</a>
232
+
233
+ For two partial specializations, the first is *more specialized* than
234
+ the second if, given the following rewrite to two function templates,
235
+ the first function template is more specialized than the second
236
+ according to the ordering rules for function templates
237
+ [[temp.func.order]]:
238
+
239
+ - Each of the two function templates has the same template parameters
240
+ and associated constraints [[temp.constr.decl]] as the corresponding
241
+ partial specialization.
242
+ - Each function template has a single function parameter whose type is a
243
+ class template specialization where the template arguments are the
244
+ corresponding template parameters from the function template for each
245
+ template argument in the *template-argument-list* of the
246
+ *simple-template-id* of the partial specialization.
247
+
248
+ [*Example 1*:
249
+
250
+ ``` cpp
251
+ template<int I, int J, class T> class X { };
252
+ template<int I, int J> class X<I, J, int> { }; // #1
253
+ template<int I> class X<I, I, int> { }; // #2
254
+
255
+ template<int I0, int J0> void f(X<I0, J0, int>); // A
256
+ template<int I0> void f(X<I0, I0, int>); // B
257
+
258
+ template <auto v> class Y { };
259
+ template <auto* p> class Y<p> { }; // #3
260
+ template <auto** pp> class Y<pp> { }; // #4
261
+
262
+ template <auto* p0> void g(Y<p0>); // C
263
+ template <auto** pp0> void g(Y<pp0>); // D
264
+ ```
265
+
266
+ According to the ordering rules for function templates, the function
267
+ template *B* is more specialized than the function template *A* and the
268
+ function template *D* is more specialized than the function template
269
+ *C*. Therefore, the partial specialization \#2 is more specialized than
270
+ the partial specialization \#1 and the partial specialization \#4 is
271
+ more specialized than the partial specialization \#3.
272
+
273
+ — *end example*]
274
+
275
+ [*Example 2*:
276
+
277
+ ``` cpp
278
+ template<typename T> concept C = requires (T t) { t.f(); };
279
+ template<typename T> concept D = C<T> && requires (T t) { t.f(); };
280
+
281
+ template<typename T> class S { };
282
+ template<C T> class S<T> { }; // #1
283
+ template<D T> class S<T> { }; // #2
284
+
285
+ template<C T> void f(S<T>); // A
286
+ template<D T> void f(S<T>); // B
287
+ ```
288
+
289
+ The partial specialization \#2 is more specialized than \#1 because `B`
290
+ is more specialized than `A`.
291
+
292
+ — *end example*]
293
+
294
+ #### Members of class template partial specializations <a id="temp.spec.partial.member">[[temp.spec.partial.member]]</a>
295
+
296
+ The members of the class template partial specialization are unrelated
297
+ to the members of the primary template. Class template partial
298
+ specialization members that are used in a way that requires a definition
299
+ shall be defined; the definitions of members of the primary template are
300
+ never used as definitions for members of a class template partial
301
+ specialization. An explicit specialization of a member of a class
302
+ template partial specialization is declared in the same way as an
303
+ explicit specialization of a member of the primary template.
304
+
305
+ [*Example 1*:
306
+
307
+ ``` cpp
308
+ // primary class template
309
+ template<class T, int I> struct A {
310
+ void f();
311
+ };
312
+
313
+ // member of primary class template
314
+ template<class T, int I> void A<T,I>::f() { }
315
+
316
+ // class template partial specialization
317
+ template<class T> struct A<T,2> {
318
+ void f();
319
+ void g();
320
+ void h();
321
+ };
322
+
323
+ // member of class template partial specialization
324
+ template<class T> void A<T,2>::g() { }
325
+
326
+ // explicit specialization
327
+ template<> void A<char,2>::h() { }
328
+
329
+ int main() {
330
+ A<char,0> a0;
331
+ A<char,2> a2;
332
+ a0.f(); // OK, uses definition of primary template's member
333
+ a2.g(); // OK, uses definition of partial specialization's member
334
+ a2.h(); // OK, uses definition of explicit specialization's member
335
+ a2.f(); // error: no definition of f for A<T,2>; the primary template is not used here
336
+ }
337
+ ```
338
+
339
+ — *end example*]
340
+
341
+ If a member template of a class template is partially specialized, the
342
+ member template partial specializations are member templates of the
343
+ enclosing class template; if the enclosing class template is
344
+ instantiated [[temp.inst]], [[temp.explicit]], a declaration for every
345
+ member template partial specialization is also instantiated as part of
346
+ creating the members of the class template specialization. If the
347
+ primary member template is explicitly specialized for a given (implicit)
348
+ specialization of the enclosing class template, the partial
349
+ specializations of the member template are ignored for this
350
+ specialization of the enclosing class template. If a partial
351
+ specialization of the member template is explicitly specialized for a
352
+ given (implicit) specialization of the enclosing class template, the
353
+ primary member template and its other partial specializations are still
354
+ considered for this specialization of the enclosing class template.
355
+
356
+ [*Example 2*:
357
+
358
+ ``` cpp
359
+ template<class T> struct A {
360
+ template<class T2> struct B {}; // #1
361
+ template<class T2> struct B<T2*> {}; // #2
362
+ };
363
+
364
+ template<> template<class T2> struct A<short>::B {}; // #3
365
+
366
+ A<char>::B<int*> abcip; // uses #2
367
+ A<short>::B<int*> absip; // uses #3
368
+ A<char>::B<int> abci; // uses #1
369
+ ```
370
+
371
+ — *end example*]
372
+