From Jason Turner

[temp.deduct.type]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp541svvw2/{from.md → to.md} +99 -59
tmp/tmp541svvw2/{from.md → to.md} RENAMED
@@ -20,12 +20,12 @@ deduction fails. The type of a type parameter is only deduced from an
20
  array bound if it is not otherwise deduced.
21
 
22
  A given type `P` can be composed from a number of other types,
23
  templates, and non-type values:
24
 
25
- - A function type includes the types of each of the function parameters
26
- and the return type.
27
  - A pointer-to-member type includes the type of the class object pointed
28
  to and the type of the member pointed to.
29
  - A type that is a specialization of a class template (e.g., `A<int>`)
30
  includes the types, templates, and non-type values referenced by the
31
  template argument list of the specialization.
@@ -98,14 +98,14 @@ inconsistent template argument deductions:
98
  ``` cpp
99
  template<class T> void f(T x, T y) { ... }
100
  struct A { ... };
101
  struct B : A { ... };
102
  void g(A a, B b) {
103
- f(a,b); // error: T could be A or B
104
- f(b,a); // error: T could be A or B
105
- f(a,a); // OK: T is A
106
- f(b,b); // OK: T is B
107
  }
108
  ```
109
 
110
  Here is an example where two template arguments are deduced from a
111
  single function parameter/argument pair. This can lead to conflicts that
@@ -117,13 +117,32 @@ template <class T, class U> void f( T (*)( T, U, U ) );
117
  int g1( int, float, float);
118
  char g2( int, float, float);
119
  int g3( int, char, float);
120
 
121
  void r() {
122
- f(g1); // OK: T is int and U is float
123
- f(g2); // error: T could be char or int
124
- f(g3); // error: U could be char or float
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  }
126
  ```
127
 
128
  Here is an example where a qualification conversion applies between the
129
  argument type on the function call and the deduced template argument
@@ -153,49 +172,50 @@ void t() {
153
  }
154
  ```
155
 
156
  — *end example*]
157
 
158
- A template type argument `T`, a template template argument `TT` or a
159
  template non-type argument `i` can be deduced if `P` and `A` have one of
160
  the following forms:
161
 
162
  ``` cpp
163
- T
164
- cv T
165
  T*
166
  T&
167
  T&&
168
- T[integer-constant]
169
- template-name<T> (where template-name refers to a class template)
170
- type(T)
171
- T()
172
- T(T)
173
- T type::*
174
- type T::*
175
- T T::*
176
- T (type::*)()
177
- type (T::*)()
178
- type (type::*)(T)
179
- type (T::*)(T)
180
- T (type::*)(T)
181
- T (T::*)()
182
- T (T::*)(T)
183
- type[i]
184
- template-name<i> (where template-name refers to a class template)
185
- TT<T>
186
- TT<i>
187
- TT<>
188
  ```
189
 
190
- where `(T)` represents a parameter-type-list [[dcl.fct]] where at least
191
- one parameter type contains a `T`, and `()` represents a
192
- parameter-type-list where no parameter type contains a `T`. Similarly,
193
- `<T>` represents template argument lists where at least one argument
194
- contains a `T`, `<i>` represents template argument lists where at least
195
- one argument contains an `i` and `<>` represents template argument lists
196
- where no argument contains a `T` or an `i`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
 
198
  If `P` has a form that contains `<T>` or `<i>`, then each argument Pᵢ of
199
  the respective template argument list of `P` is compared with the
200
  corresponding argument Aᵢ of the corresponding template argument list of
201
  `A`. If the template argument list of `P` contains a pack expansion that
@@ -239,11 +259,11 @@ parameters of the top-level parameter-type-list of `P` and `A`,
239
  respectively, `Pᵢ` is adjusted if it is a forwarding reference
240
  [[temp.deduct.call]] and `Aᵢ` is an lvalue reference, in which case the
241
  type of `Pᵢ` is changed to be the template parameter type (i.e., `T&&`
242
  is changed to simply `T`).
243
 
244
- [*Note 2*: As a result, when `Pᵢ` is `T&&` and `Aᵢ` is `X&`, the
245
  adjusted `Pᵢ` will be `T`, causing `T` to be deduced as
246
  `X&`. — *end note*]
247
 
248
  [*Example 5*:
249
 
@@ -346,23 +366,40 @@ using V = decltype(sizeof 0);
346
  using V = S<int[42]>::Q; // OK; T was deduced as std::size_t from the type int[42]
347
  ```
348
 
349
  — *end example*]
350
 
 
 
 
351
  [*Example 10*:
352
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
353
  ``` cpp
354
  template<class T, T i> void f(int (&a)[i]);
355
  int v[10];
356
  void g() {
357
- f(v); // OK: T is std::size_t
358
  }
359
  ```
360
 
361
  — *end example*]
362
 
363
- [*Note 3*:
364
 
365
  Except for reference and pointer types, a major array bound is not part
366
  of a function parameter type and cannot be deduced from an argument:
367
 
368
  ``` cpp
@@ -370,28 +407,28 @@ template<int i> void f1(int a[10][i]);
370
  template<int i> void f2(int a[i][20]);
371
  template<int i> void f3(int (&a)[i][20]);
372
 
373
  void g() {
374
  int v[10][20];
375
- f1(v); // OK: i deduced as 20
376
  f1<20>(v); // OK
377
  f2(v); // error: cannot deduce template-argument i
378
  f2<10>(v); // OK
379
- f3(v); // OK: i deduced as 10
380
  }
381
  ```
382
 
383
  — *end note*]
384
 
385
- [*Note 4*:
386
 
387
  If, in the declaration of a function template with a non-type template
388
  parameter, the non-type template parameter is used in a subexpression in
389
  the function parameter list, the expression is a non-deduced context as
390
  specified above.
391
 
392
- [*Example 11*:
393
 
394
  ``` cpp
395
  template <int i> class A { ... };
396
  template <int i> void g(A<i+1>);
397
  template <int i> void f(A<i>, A<i+1>);
@@ -406,11 +443,11 @@ void k() {
406
 
407
  — *end example*]
408
 
409
  — *end note*]
410
 
411
- [*Note 5*:
412
 
413
  Template parameters do not participate in template argument deduction if
414
  they are used only in non-deduced contexts. For example,
415
 
416
  ``` cpp
@@ -430,13 +467,16 @@ int x = deduce<77>(a.xm, 62, b.ym);
430
 
431
  If `P` has a form that contains `<i>`, and if the type of `i` differs
432
  from the type of the corresponding template parameter of the template
433
  named by the enclosing *simple-template-id*, deduction fails. If `P` has
434
  a form that contains `[i]`, and if the type of `i` is not an integral
435
- type, deduction fails.[^13]
436
 
437
- [*Example 12*:
 
 
 
438
 
439
  ``` cpp
440
  template<int i> class A { ... };
441
  template<short s> void f(A<s>);
442
  void k1() {
@@ -447,20 +487,20 @@ void k1() {
447
 
448
  template<const short cs> class B { };
449
  template<short s> void g(B<s>);
450
  void k2() {
451
  B<1> b;
452
- g(b); // OK: cv-qualifiers are ignored on template parameter types
453
  }
454
  ```
455
 
456
  — *end example*]
457
 
458
  A *template-argument* can be deduced from a function, pointer to
459
  function, or pointer-to-member-function type.
460
 
461
- [*Example 13*:
462
 
463
  ``` cpp
464
  template<class T> void f(void(*)(T,int));
465
  template<class T> void foo(T,int);
466
  void g(int,int);
@@ -468,38 +508,38 @@ void g(char,int);
468
 
469
  void h(int,int,int);
470
  void h(char,int);
471
  int m() {
472
  f(&g); // error: ambiguous
473
- f(&h); // OK: void h(char,int) is a unique match
474
  f(&foo); // error: type deduction fails because foo is a template
475
  }
476
  ```
477
 
478
  — *end example*]
479
 
480
  A template *type-parameter* cannot be deduced from the type of a
481
  function default argument.
482
 
483
- [*Example 14*:
484
 
485
  ``` cpp
486
  template <class T> void f(T = 5, T = 7);
487
  void g() {
488
- f(1); // OK: call f<int>(1,7)
489
  f(); // error: cannot deduce T
490
- f<int>(); // OK: call f<int>(5,7)
491
  }
492
  ```
493
 
494
  — *end example*]
495
 
496
  The *template-argument* corresponding to a template *template-parameter*
497
  is deduced from the type of the *template-argument* of a class template
498
  specialization used in the argument list of a function call.
499
 
500
- [*Example 15*:
501
 
502
  ``` cpp
503
  template <template <class T> class X> struct A { };
504
  template <template <class T> class X> void f(A<X>) { }
505
  template<class T> struct B { };
@@ -507,15 +547,15 @@ A<B> ab;
507
  f(ab); // calls f(A<B>)
508
  ```
509
 
510
  — *end example*]
511
 
512
- [*Note 6*: Template argument deduction involving parameter packs
513
  [[temp.variadic]] can deduce zero or more arguments for each parameter
514
  pack. — *end note*]
515
 
516
- [*Example 16*:
517
 
518
  ``` cpp
519
  template<class> struct X { };
520
  template<class R, class ... ArgTypes> struct X<R(int, ArgTypes ...)> { };
521
  template<class ... Types> struct Y { };
@@ -525,11 +565,11 @@ template<class ... Types> int f(void (*)(Types ...));
525
  void g(int, float);
526
 
527
  X<int> x1; // uses primary template
528
  X<int(int, float, double)> x2; // uses partial specialization; ArgTypes contains float, double
529
  X<int(float, int)> x3; // uses primary template
530
- Y<> y1; // use primary template; Types is empty
531
  Y<int&, float&, double&> y2; // uses partial specialization; T is int&, Types contains float, double
532
  Y<int, float, double> y3; // uses primary template; Types contains int, float, double
533
  int fv = f(g); // OK; Types contains int, float
534
  ```
535
 
 
20
  array bound if it is not otherwise deduced.
21
 
22
  A given type `P` can be composed from a number of other types,
23
  templates, and non-type values:
24
 
25
+ - A function type includes the types of each of the function parameters,
26
+ the return type, and its exception specification.
27
  - A pointer-to-member type includes the type of the class object pointed
28
  to and the type of the member pointed to.
29
  - A type that is a specialization of a class template (e.g., `A<int>`)
30
  includes the types, templates, and non-type values referenced by the
31
  template argument list of the specialization.
 
98
  ``` cpp
99
  template<class T> void f(T x, T y) { ... }
100
  struct A { ... };
101
  struct B : A { ... };
102
  void g(A a, B b) {
103
+ f(a,b); // error: T deduced as both A and B
104
+ f(b,a); // error: T deduced as both A and B
105
+ f(a,a); // OK, T is A
106
+ f(b,b); // OK, T is B
107
  }
108
  ```
109
 
110
  Here is an example where two template arguments are deduced from a
111
  single function parameter/argument pair. This can lead to conflicts that
 
117
  int g1( int, float, float);
118
  char g2( int, float, float);
119
  int g3( int, char, float);
120
 
121
  void r() {
122
+ f(g1); // OK, T is int and U is float
123
+ f(g2); // error: T deduced as both char and int
124
+ f(g3); // error: U deduced as both char and float
125
+ }
126
+ ```
127
+
128
+ Here is an example where the exception specification of a function type
129
+ is deduced:
130
+
131
+ ``` cpp
132
+ template<bool E> void f1(void (*)() noexcept(E));
133
+ template<bool> struct A { };
134
+ template<bool B> void f2(void (*)(A<B>) noexcept(B));
135
+
136
+ void g1();
137
+ void g2() noexcept;
138
+ void g3(A<true>);
139
+
140
+ void h() {
141
+ f1(g1); // OK, E is false
142
+ f1(g2); // OK, E is true
143
+ f2(g3); // error: B deduced as both true and false
144
  }
145
  ```
146
 
147
  Here is an example where a qualification conversion applies between the
148
  argument type on the function call and the deduced template argument
 
172
  }
173
  ```
174
 
175
  — *end example*]
176
 
177
+ A template type argument `T`, a template template argument `TT`, or a
178
  template non-type argument `i` can be deduced if `P` and `A` have one of
179
  the following forms:
180
 
181
  ``` cpp
182
+ \opt{cv} T
 
183
  T*
184
  T&
185
  T&&
186
+ \opt{T}[\opt{i}]
187
+ \opt{T}(\opt{T}) noexcept(\opt{i})
188
+ \opt{T} \opt{T}::*
189
+ \opt{TT}<T>
190
+ \opt{TT}<i>
191
+ \opt{TT}<TT>
192
+ \opt{TT}<>
 
 
 
 
 
 
 
 
 
 
 
 
 
193
  ```
194
 
195
+ where
196
+
197
+ - `\opt{T}` represents a type or parameter-type-list that either
198
+ satisfies these rules recursively, is a non-deduced context in `P` or
199
+ `A`, or is the same non-dependent type in `P` and `A`,
200
+ - `\opt{TT}` represents either a class template or a template template
201
+ parameter,
202
+ - `\opt{i}` represents an expression that either is an `i`, is
203
+ value-dependent in `P` or `A`, or has the same constant value in `P`
204
+ and `A`, and
205
+ - `noexcept(\opt{i})` represents an exception specification
206
+ [[except.spec]] in which the (possibly-implicit, see  [[dcl.fct]])
207
+ *noexcept-specifier*’s operand satisfies the rules for an `\opt{i}`
208
+ above.
209
+
210
+ [*Note 2*: If a type matches such a form but contains no `T`s, `i`s, or
211
+ `TT`s, deduction is not possible. — *end note*]
212
+
213
+ Similarly, `<T>` represents template argument lists where at least one
214
+ argument contains a `T`, `<i>` represents template argument lists where
215
+ at least one argument contains an `i` and `<>` represents template
216
+ argument lists where no argument contains a `T` or an `i`.
217
 
218
  If `P` has a form that contains `<T>` or `<i>`, then each argument Pᵢ of
219
  the respective template argument list of `P` is compared with the
220
  corresponding argument Aᵢ of the corresponding template argument list of
221
  `A`. If the template argument list of `P` contains a pack expansion that
 
259
  respectively, `Pᵢ` is adjusted if it is a forwarding reference
260
  [[temp.deduct.call]] and `Aᵢ` is an lvalue reference, in which case the
261
  type of `Pᵢ` is changed to be the template parameter type (i.e., `T&&`
262
  is changed to simply `T`).
263
 
264
+ [*Note 3*: As a result, when `Pᵢ` is `T&&` and `Aᵢ` is `X&`, the
265
  adjusted `Pᵢ` will be `T`, causing `T` to be deduced as
266
  `X&`. — *end note*]
267
 
268
  [*Example 5*:
269
 
 
366
  using V = S<int[42]>::Q; // OK; T was deduced as std::size_t from the type int[42]
367
  ```
368
 
369
  — *end example*]
370
 
371
+ The type of `B` in the *noexcept-specifier* `noexcept(B)` of a function
372
+ type is `bool`.
373
+
374
  [*Example 10*:
375
 
376
+ ``` cpp
377
+ template<bool> struct A { };
378
+ template<auto> struct B;
379
+ template<auto X, void (*F)() noexcept(X)> struct B<F> {
380
+ A<X> ax;
381
+ };
382
+ void f_nothrow() noexcept;
383
+ B<f_nothrow> bn; // OK, type of X deduced as bool
384
+ ```
385
+
386
+ — *end example*]
387
+
388
+ [*Example 11*:
389
+
390
  ``` cpp
391
  template<class T, T i> void f(int (&a)[i]);
392
  int v[10];
393
  void g() {
394
+ f(v); // OK, T is std::size_t
395
  }
396
  ```
397
 
398
  — *end example*]
399
 
400
+ [*Note 4*:
401
 
402
  Except for reference and pointer types, a major array bound is not part
403
  of a function parameter type and cannot be deduced from an argument:
404
 
405
  ``` cpp
 
407
  template<int i> void f2(int a[i][20]);
408
  template<int i> void f3(int (&a)[i][20]);
409
 
410
  void g() {
411
  int v[10][20];
412
+ f1(v); // OK, i deduced as 20
413
  f1<20>(v); // OK
414
  f2(v); // error: cannot deduce template-argument i
415
  f2<10>(v); // OK
416
+ f3(v); // OK, i deduced as 10
417
  }
418
  ```
419
 
420
  — *end note*]
421
 
422
+ [*Note 5*:
423
 
424
  If, in the declaration of a function template with a non-type template
425
  parameter, the non-type template parameter is used in a subexpression in
426
  the function parameter list, the expression is a non-deduced context as
427
  specified above.
428
 
429
+ [*Example 12*:
430
 
431
  ``` cpp
432
  template <int i> class A { ... };
433
  template <int i> void g(A<i+1>);
434
  template <int i> void f(A<i>, A<i+1>);
 
443
 
444
  — *end example*]
445
 
446
  — *end note*]
447
 
448
+ [*Note 6*:
449
 
450
  Template parameters do not participate in template argument deduction if
451
  they are used only in non-deduced contexts. For example,
452
 
453
  ``` cpp
 
467
 
468
  If `P` has a form that contains `<i>`, and if the type of `i` differs
469
  from the type of the corresponding template parameter of the template
470
  named by the enclosing *simple-template-id*, deduction fails. If `P` has
471
  a form that contains `[i]`, and if the type of `i` is not an integral
472
+ type, deduction fails.[^14]
473
 
474
+ If `P` has a form that includes `noexcept(i)` and the type of `i` is not
475
+ `bool`, deduction fails.
476
+
477
+ [*Example 13*:
478
 
479
  ``` cpp
480
  template<int i> class A { ... };
481
  template<short s> void f(A<s>);
482
  void k1() {
 
487
 
488
  template<const short cs> class B { };
489
  template<short s> void g(B<s>);
490
  void k2() {
491
  B<1> b;
492
+ g(b); // OK, cv-qualifiers are ignored on template parameter types
493
  }
494
  ```
495
 
496
  — *end example*]
497
 
498
  A *template-argument* can be deduced from a function, pointer to
499
  function, or pointer-to-member-function type.
500
 
501
+ [*Example 14*:
502
 
503
  ``` cpp
504
  template<class T> void f(void(*)(T,int));
505
  template<class T> void foo(T,int);
506
  void g(int,int);
 
508
 
509
  void h(int,int,int);
510
  void h(char,int);
511
  int m() {
512
  f(&g); // error: ambiguous
513
+ f(&h); // OK, void h(char,int) is a unique match
514
  f(&foo); // error: type deduction fails because foo is a template
515
  }
516
  ```
517
 
518
  — *end example*]
519
 
520
  A template *type-parameter* cannot be deduced from the type of a
521
  function default argument.
522
 
523
+ [*Example 15*:
524
 
525
  ``` cpp
526
  template <class T> void f(T = 5, T = 7);
527
  void g() {
528
+ f(1); // OK, calls f<int>(1,7)
529
  f(); // error: cannot deduce T
530
+ f<int>(); // OK, calls f<int>(5,7)
531
  }
532
  ```
533
 
534
  — *end example*]
535
 
536
  The *template-argument* corresponding to a template *template-parameter*
537
  is deduced from the type of the *template-argument* of a class template
538
  specialization used in the argument list of a function call.
539
 
540
+ [*Example 16*:
541
 
542
  ``` cpp
543
  template <template <class T> class X> struct A { };
544
  template <template <class T> class X> void f(A<X>) { }
545
  template<class T> struct B { };
 
547
  f(ab); // calls f(A<B>)
548
  ```
549
 
550
  — *end example*]
551
 
552
+ [*Note 7*: Template argument deduction involving parameter packs
553
  [[temp.variadic]] can deduce zero or more arguments for each parameter
554
  pack. — *end note*]
555
 
556
+ [*Example 17*:
557
 
558
  ``` cpp
559
  template<class> struct X { };
560
  template<class R, class ... ArgTypes> struct X<R(int, ArgTypes ...)> { };
561
  template<class ... Types> struct Y { };
 
565
  void g(int, float);
566
 
567
  X<int> x1; // uses primary template
568
  X<int(int, float, double)> x2; // uses partial specialization; ArgTypes contains float, double
569
  X<int(float, int)> x3; // uses primary template
570
+ Y<> y1; // uses primary template; Types is empty
571
  Y<int&, float&, double&> y2; // uses partial specialization; T is int&, Types contains float, double
572
  Y<int, float, double> y3; // uses primary template; Types contains int, float, double
573
  int fv = f(g); // OK; Types contains int, float
574
  ```
575