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 |
-
|
| 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
|
| 104 |
-
f(b,a); // error: T
|
| 105 |
-
f(a,a); // OK
|
| 106 |
-
f(b,b); // OK
|
| 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
|
| 123 |
-
f(g2); // error: T
|
| 124 |
-
f(g3); // error: U
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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[
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
T
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
| 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
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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
|
| 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
|
| 358 |
}
|
| 359 |
```
|
| 360 |
|
| 361 |
— *end example*]
|
| 362 |
|
| 363 |
-
[*Note
|
| 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
|
| 376 |
f1<20>(v); // OK
|
| 377 |
f2(v); // error: cannot deduce template-argument i
|
| 378 |
f2<10>(v); // OK
|
| 379 |
-
f3(v); // OK
|
| 380 |
}
|
| 381 |
```
|
| 382 |
|
| 383 |
— *end note*]
|
| 384 |
|
| 385 |
-
[*Note
|
| 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
|
| 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
|
| 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.[^
|
| 436 |
|
| 437 |
-
|
|
|
|
|
|
|
|
|
|
| 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
|
| 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
|
| 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
|
| 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
|
| 484 |
|
| 485 |
``` cpp
|
| 486 |
template <class T> void f(T = 5, T = 7);
|
| 487 |
void g() {
|
| 488 |
-
f(1); // OK
|
| 489 |
f(); // error: cannot deduce T
|
| 490 |
-
f<int>(); // OK
|
| 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
|
| 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
|
| 513 |
[[temp.variadic]] can deduce zero or more arguments for each parameter
|
| 514 |
pack. — *end note*]
|
| 515 |
|
| 516 |
-
[*Example
|
| 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; //
|
| 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 |
|