From Jason Turner

[temp.deduct.general]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp0n6oym93/{from.md → to.md} +394 -0
tmp/tmp0n6oym93/{from.md → to.md} RENAMED
@@ -0,0 +1,394 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #### General <a id="temp.deduct.general">[[temp.deduct.general]]</a>
2
+
3
+ When a function template specialization is referenced, all of the
4
+ template arguments shall have values. The values can be explicitly
5
+ specified or, in some cases, be deduced from the use or obtained from
6
+ default *template-argument*s.
7
+
8
+ [*Example 1*:
9
+
10
+ ``` cpp
11
+ void f(Array<dcomplex>& cv, Array<int>& ci) {
12
+ sort(cv); // calls sort(Array<dcomplex>&)
13
+ sort(ci); // calls sort(Array<int>&)
14
+ }
15
+ ```
16
+
17
+ and
18
+
19
+ ``` cpp
20
+ void g(double d) {
21
+ int i = convert<int>(d); // calls convert<int,double>(double)
22
+ int c = convert<char>(d); // calls convert<char,double>(double)
23
+ }
24
+ ```
25
+
26
+ — *end example*]
27
+
28
+ When an explicit template argument list is specified, if the given
29
+ *template-id* is not valid [[temp.names]], type deduction fails.
30
+ Otherwise, the specified template argument values are substituted for
31
+ the corresponding template parameters as specified below.
32
+
33
+ After this substitution is performed, the function parameter type
34
+ adjustments described in  [[dcl.fct]] are performed.
35
+
36
+ [*Example 2*: A parameter type of “`void (const int, int[5])`” becomes
37
+ “`void(*)(int,int*)`”. — *end example*]
38
+
39
+ [*Note 1*: A top-level qualifier in a function parameter declaration
40
+ does not affect the function type but still affects the type of the
41
+ function parameter variable within the function. — *end note*]
42
+
43
+ [*Example 3*:
44
+
45
+ ``` cpp
46
+ template <class T> void f(T t);
47
+ template <class X> void g(const X x);
48
+ template <class Z> void h(Z, Z*);
49
+
50
+ int main() {
51
+ // #1: function type is f(int), t is non const
52
+ f<int>(1);
53
+
54
+ // #2: function type is f(int), t is const
55
+ f<const int>(1);
56
+
57
+ // #3: function type is g(int), x is const
58
+ g<int>(1);
59
+
60
+ // #4: function type is g(int), x is const
61
+ g<const int>(1);
62
+
63
+ // #5: function type is h(int, const int*)
64
+ h<const int>(1,0);
65
+ }
66
+ ```
67
+
68
+ — *end example*]
69
+
70
+ [*Note 2*: `f<int>(1)` and `f<const int>(1)` call distinct functions
71
+ even though both of the functions called have the same function
72
+ type. — *end note*]
73
+
74
+ The resulting substituted and adjusted function type is used as the type
75
+ of the function template for template argument deduction. If a template
76
+ argument has not been deduced and its corresponding template parameter
77
+ has a default argument, the template argument is determined by
78
+ substituting the template arguments determined for preceding template
79
+ parameters into the default argument. If the substitution results in an
80
+ invalid type, as described above, type deduction fails.
81
+
82
+ [*Example 4*:
83
+
84
+ ``` cpp
85
+ template <class T, class U = double>
86
+ void f(T t = 0, U u = 0);
87
+
88
+ void g() {
89
+ f(1, 'c'); // f<int,char>(1,'c')
90
+ f(1); // f<int,double>(1,0)
91
+ f(); // error: T cannot be deduced
92
+ f<int>(); // f<int,double>(0,0)
93
+ f<int,char>(); // f<int,char>(0,0)
94
+ }
95
+ ```
96
+
97
+ — *end example*]
98
+
99
+ When all template arguments have been deduced or obtained from default
100
+ template arguments, all uses of template parameters in the template
101
+ parameter list of the template are replaced with the corresponding
102
+ deduced or default argument values. If the substitution results in an
103
+ invalid type, as described above, type deduction fails. If the function
104
+ template has associated constraints [[temp.constr.decl]], those
105
+ constraints are checked for satisfaction [[temp.constr.constr]]. If the
106
+ constraints are not satisfied, type deduction fails. In the context of a
107
+ function call, if type deduction has not yet failed, then for those
108
+ function parameters for which the function call has arguments, each
109
+ function parameter with a type that was non-dependent before
110
+ substitution of any explicitly-specified template arguments is checked
111
+ against its corresponding argument; if the corresponding argument cannot
112
+ be implicitly converted to the parameter type, type deduction fails.
113
+
114
+ [*Note 3*: Overload resolution will check the other parameters,
115
+ including parameters with dependent types in which no template
116
+ parameters participate in template argument deduction and parameters
117
+ that became non-dependent due to substitution of explicitly-specified
118
+ template arguments. — *end note*]
119
+
120
+ If type deduction has not yet failed, then all uses of template
121
+ parameters in the function type are replaced with the corresponding
122
+ deduced or default argument values. If the substitution results in an
123
+ invalid type, as described above, type deduction fails.
124
+
125
+ [*Example 5*:
126
+
127
+ ``` cpp
128
+ template <class T> struct Z {
129
+ typedef typename T::x xx;
130
+ };
131
+ template <class T> concept C = requires { typename T::A; };
132
+ template <C T> typename Z<T>::xx f(void *, T); // #1
133
+ template <class T> void f(int, T); // #2
134
+ struct A {} a;
135
+ struct ZZ {
136
+ template <class T, class = typename Z<T>::xx> operator T *();
137
+ operator int();
138
+ };
139
+ int main() {
140
+ ZZ zz;
141
+ f(1, a); // OK, deduction fails for #1 because there is no conversion from int to void*
142
+ f(zz, 42); // OK, deduction fails for #1 because C<int> is not satisfied
143
+ }
144
+ ```
145
+
146
+ — *end example*]
147
+
148
+ At certain points in the template argument deduction process it is
149
+ necessary to take a function type that makes use of template parameters
150
+ and replace those template parameters with the corresponding template
151
+ arguments. This is done at the beginning of template argument deduction
152
+ when any explicitly specified template arguments are substituted into
153
+ the function type, and again at the end of template argument deduction
154
+ when any template arguments that were deduced or obtained from default
155
+ arguments are substituted.
156
+
157
+ The *deduction substitution loci* are
158
+
159
+ - the function type outside of the *noexcept-specifier*,
160
+ - the *explicit-specifier*, and
161
+ - the template parameter declarations.
162
+
163
+ The substitution occurs in all types and expressions that are used in
164
+ the deduction substitution loci. The expressions include not only
165
+ constant expressions such as those that appear in array bounds or as
166
+ nontype template arguments but also general expressions (i.e.,
167
+ non-constant expressions) inside `sizeof`, `decltype`, and other
168
+ contexts that allow non-constant expressions. The substitution proceeds
169
+ in lexical order and stops when a condition that causes deduction to
170
+ fail is encountered. If substitution into different declarations of the
171
+ same function template would cause template instantiations to occur in a
172
+ different order or not at all, the program is ill-formed; no diagnostic
173
+ required.
174
+
175
+ [*Note 4*: The equivalent substitution in exception specifications is
176
+ done only when the *noexcept-specifier* is instantiated, at which point
177
+ a program is ill-formed if the substitution results in an invalid type
178
+ or expression. — *end note*]
179
+
180
+ [*Example 6*:
181
+
182
+ ``` cpp
183
+ template <class T> struct A { using X = typename T::X; };
184
+ template <class T> typename T::X f(typename A<T>::X);
185
+ template <class T> void f(...) { }
186
+ template <class T> auto g(typename A<T>::X) -> typename T::X;
187
+ template <class T> void g(...) { }
188
+ template <class T> typename T::X h(typename A<T>::X);
189
+ template <class T> auto h(typename A<T>::X) -> typename T::X; // redeclaration
190
+ template <class T> void h(...) { }
191
+
192
+ void x() {
193
+ f<int>(0); // OK, substituting return type causes deduction to fail
194
+ g<int>(0); // error, substituting parameter type instantiates A<int>
195
+ h<int>(0); // ill-formed, no diagnostic required
196
+ }
197
+ ```
198
+
199
+ — *end example*]
200
+
201
+ If a substitution results in an invalid type or expression, type
202
+ deduction fails. An invalid type or expression is one that would be
203
+ ill-formed, with a diagnostic required, if written in the same context
204
+ using the substituted arguments.
205
+
206
+ [*Note 5*: If no diagnostic is required, the program is still
207
+ ill-formed. Access checking is done as part of the substitution
208
+ process. — *end note*]
209
+
210
+ Invalid types and expressions can result in a deduction failure only in
211
+ the immediate context of the deduction substitution loci.
212
+
213
+ [*Note 6*: The substitution into types and expressions can result in
214
+ effects such as the instantiation of class template specializations
215
+ and/or function template specializations, the generation of
216
+ implicitly-defined functions, etc. Such effects are not in the
217
+ “immediate context” and can result in the program being
218
+ ill-formed. — *end note*]
219
+
220
+ A *lambda-expression* appearing in a function type or a template
221
+ parameter is not considered part of the immediate context for the
222
+ purposes of template argument deduction.
223
+
224
+ [*Note 7*:
225
+
226
+ The intent is to avoid requiring implementations to deal with
227
+ substitution failure involving arbitrary statements.
228
+
229
+ [*Example 7*:
230
+
231
+ ``` cpp
232
+ template <class T>
233
+ auto f(T) -> decltype([]() { T::invalid; } ());
234
+ void f(...);
235
+ f(0); // error: invalid expression not part of the immediate context
236
+
237
+ template <class T, std::size_t = sizeof([]() { T::invalid; })>
238
+ void g(T);
239
+ void g(...);
240
+ g(0); // error: invalid expression not part of the immediate context
241
+
242
+ template <class T>
243
+ auto h(T) -> decltype([x = T::invalid]() { });
244
+ void h(...);
245
+ h(0); // error: invalid expression not part of the immediate context
246
+
247
+ template <class T>
248
+ auto i(T) -> decltype([]() -> typename T::invalid { });
249
+ void i(...);
250
+ i(0); // error: invalid expression not part of the immediate context
251
+
252
+ template <class T>
253
+ auto j(T t) -> decltype([](auto x) -> decltype(x.invalid) { } (t)); // #1
254
+ void j(...); // #2
255
+ j(0); // deduction fails on #1, calls #2
256
+ ```
257
+
258
+ — *end example*]
259
+
260
+ — *end note*]
261
+
262
+ [*Example 8*:
263
+
264
+ ``` cpp
265
+ struct X { };
266
+ struct Y {
267
+ Y(X) {}
268
+ };
269
+
270
+ template <class T> auto f(T t1, T t2) -> decltype(t1 + t2); // #1
271
+ X f(Y, Y); // #2
272
+
273
+ X x1, x2;
274
+ X x3 = f(x1, x2); // deduction fails on #1 (cannot add X+X), calls #2
275
+ ```
276
+
277
+ — *end example*]
278
+
279
+ [*Note 8*:
280
+
281
+ Type deduction can fail for the following reasons:
282
+
283
+ - Attempting to instantiate a pack expansion containing multiple packs
284
+ of differing lengths.
285
+ - Attempting to create an array with an element type that is `void`, a
286
+ function type, or a reference type, or attempting to create an array
287
+ with a size that is zero or negative.
288
+ \[*Example 9*:
289
+ ``` cpp
290
+ template <class T> int f(T[5]);
291
+ int I = f<int>(0);
292
+ int j = f<void>(0); // invalid array
293
+ ```
294
+
295
+ — *end example*]
296
+ - Attempting to use a type that is not a class or enumeration type in a
297
+ qualified name.
298
+ \[*Example 10*:
299
+ ``` cpp
300
+ template <class T> int f(typename T::B*);
301
+ int i = f<int>(0);
302
+ ```
303
+
304
+ — *end example*]
305
+ - Attempting to use a type in a *nested-name-specifier* of a
306
+ *qualified-id* when that type does not contain the specified member,
307
+ or
308
+ - the specified member is not a type where a type is required, or
309
+ - the specified member is not a template where a template is required,
310
+ or
311
+ - the specified member is not a non-type where a non-type is required.
312
+
313
+ \[*Example 11*:
314
+ ``` cpp
315
+ template <int I> struct X { };
316
+ template <template <class T> class> struct Z { };
317
+ template <class T> void f(typename T::Y*) {}
318
+ template <class T> void g(X<T::N>*) {}
319
+ template <class T> void h(Z<T::TT>*) {}
320
+ struct A {};
321
+ struct B { int Y; };
322
+ struct C {
323
+ typedef int N;
324
+ };
325
+ struct D {
326
+ typedef int TT;
327
+ };
328
+
329
+ int main() {
330
+ // Deduction fails in each of these cases:
331
+ f<A>(0); // A does not contain a member Y
332
+ f<B>(0); // The Y member of B is not a type
333
+ g<C>(0); // The N member of C is not a non-type
334
+ h<D>(0); // The TT member of D is not a template
335
+ }
336
+ ```
337
+
338
+ — *end example*]
339
+ - Attempting to create a pointer to reference type.
340
+ - Attempting to create a reference to `void`.
341
+ - Attempting to create “pointer to member of `T`” when `T` is not a
342
+ class type.
343
+ \[*Example 12*:
344
+ ``` cpp
345
+ template <class T> int f(int T::*);
346
+ int i = f<int>(0);
347
+ ```
348
+
349
+ — *end example*]
350
+ - Attempting to give an invalid type to a non-type template parameter.
351
+ \[*Example 13*:
352
+ ``` cpp
353
+ template <class T, T> struct S {};
354
+ template <class T> int f(S<T, T{}>*); // #1
355
+ class X {
356
+ int m;
357
+ };
358
+ int i0 = f<X>(0); // #1 uses a value of non-structural type X as a non-type template argument
359
+ ```
360
+
361
+ — *end example*]
362
+ - Attempting to perform an invalid conversion in either a template
363
+ argument expression, or an expression used in the function
364
+ declaration.
365
+ \[*Example 14*:
366
+ ``` cpp
367
+ template <class T, T*> int f(int);
368
+ int i2 = f<int,1>(0); // can't convert 1 to int*
369
+ ```
370
+
371
+ — *end example*]
372
+ - Attempting to create a function type in which a parameter has a type
373
+ of `void`, or in which the return type is a function type or array
374
+ type.
375
+
376
+ — *end note*]
377
+
378
+ [*Example 15*:
379
+
380
+ In the following example, assuming a `signed char` cannot represent the
381
+ value 1000, a narrowing conversion [[dcl.init.list]] would be required
382
+ to convert the *template-argument* of type `int` to `signed char`,
383
+ therefore substitution fails for the second template
384
+ [[temp.arg.nontype]].
385
+
386
+ ``` cpp
387
+ template <int> int f(int);
388
+ template <signed char> int f(int);
389
+ int i1 = f<1000>(0); // OK
390
+ int i2 = f<1>(0); // ambiguous; not narrowing
391
+ ```
392
+
393
+ — *end example*]
394
+