When a
function template
specialization is referenced, all of the
template arguments shall have values.

The values can be
explicitly specified or, in some cases, be deduced from the use
or obtained from default
*template-argument**s*.

[*Example 1*: *end example*]

void f(Array<dcomplex>& cv, Array<int>& ci) {
sort(cv); // calls sort(Array<dcomplex>&)
sort(ci); // calls sort(Array<int>&)
}
and
void g(double d) {
int i = convert<int>(d); // calls convert<int,double>(double)
int c = convert<char>(d); // calls convert<char,double>(double)
}

— When an explicit template argument list is specified, if the
given *template-id* is not valid ([temp.names]),
type deduction fails.

Otherwise, the specified template argument values are substituted for the
corresponding template parameters as specified below.

After this substitution is performed, the function parameter type
adjustments described in [dcl.fct] are performed.

[*Example 3*: template <class T> void f(T t);
template <class X> void g(const X x);
template <class Z> void h(Z, Z*);
int main() {
// #1: function type is f(int), t is non const
f<int>(1);
// #2: function type is f(int), t is const
f<const int>(1);
// #3: function type is g(int), x is const
g<int>(1);
// #4: function type is g(int), x is const
g<const int>(1);
// #5: function type is h(int, const int*)
h<const int>(1,0);
}
— *end example*]

The resulting substituted and adjusted function type is used as
the type of the function template for template argument
deduction.

If a template argument has not been deduced and its
corresponding template parameter has a default argument, the
template argument is determined by substituting the template
arguments determined for preceding template parameters into the
default argument.

If the substitution results in an invalid type,
as described above, type deduction fails.

[*Example 4*: template <class T, class U = double>
void f(T t = 0, U u = 0);
void g() {
f(1, 'c'); // f<int,char>(1,'c')
f(1); // f<int,double>(1,0)
f(); // error: T cannot be deduced
f<int>(); // f<int,double>(0,0)
f<int,char>(); // f<int,char>(0,0)
}
— *end example*]

When all template arguments have been deduced or obtained from
default template arguments, all uses of template parameters in
the template parameter list of the template
are replaced with the corresponding deduced
or default argument values.

If the substitution results in an
invalid type, as described above, type deduction fails.

If the function template has associated constraints ([temp.constr.decl]),
those constraints are checked for satisfaction ([temp.constr.constr]).

If the constraints are not satisfied, type deduction fails.

In the context of a function call, if type deduction has not yet failed, then
for those function parameters for which the function call has arguments,
each function parameter with a type that was non-dependent
before substitution of any explicitly-specified template arguments
is checked against its corresponding argument;
if the corresponding argument cannot be implicitly converted
to the parameter type, type deduction fails.

If type deduction has not yet failed, then
all uses of template parameters in the function type are
replaced with the corresponding deduced or default argument values.

If the substitution results in an invalid type, as described above,
type deduction fails.

[*Example 5*: template <class T> struct Z {
typedef typename T::x xx;
};
template <class T> concept C = requires { typename T::A; };
template <C T> typename Z<T>::xx f(void *, T); // #1
template <class T> void f(int, T); // #2
struct A {} a;
struct ZZ {
template <class T, class = typename Z<T>::xx> operator T *();
operator int();
};
int main() {
ZZ zz;
f(1, a); // OK, deduction fails for #1 because there is no conversion from int to void*
f(zz, 42); // OK, deduction fails for #1 because C<int> is not satisfied
}
— *end example*]

At certain points in the template argument deduction process it is necessary
to take a function type that makes use of template parameters and replace those
template parameters with the corresponding template arguments.

This is done at
the beginning of template argument deduction when any explicitly specified
template arguments are substituted into the function type, and again at the end
of template argument deduction when any template arguments that were deduced or
obtained from default arguments are substituted.

The *deduction substitution loci* are

- the function type outside of the
*noexcept-specifier*, - the
*explicit-specifier*, and - the template parameter declarations.

The substitution occurs in all types and expressions that are used
in the deduction substitution loci.

The expressions include not only
constant expressions such as those that appear in array bounds or as nontype
template arguments but also general expressions (i.e., non-constant expressions)
inside sizeof, decltype, and other contexts that allow non-constant
expressions.

The substitution proceeds in lexical order and stops when
a condition that causes deduction to fail is encountered.

If substitution into different declarations of the same function template would
cause template instantiations to occur in a different order or not at all,
the program is ill-formed; no diagnostic required.

[*Note 4*: *end note*]

The equivalent substitution in exception specifications is
done only when the *noexcept-specifier* is instantiated,
at which point a program is ill-formed
if the substitution results in an invalid type or expression.

— [*Example 6*: template <class T> struct A { using X = typename T::X; };
template <class T> typename T::X f(typename A<T>::X);
template <class T> void f(...) { }
template <class T> auto g(typename A<T>::X) -> typename T::X;
template <class T> void g(...) { }
template <class T> typename T::X h(typename A<T>::X);
template <class T> auto h(typename A<T>::X) -> typename T::X; // redeclaration
template <class T> void h(...) { }
void x() {
f<int>(0); // OK, substituting return type causes deduction to fail
g<int>(0); // error, substituting parameter type instantiates A<int>
h<int>(0); // ill-formed, no diagnostic required
}
— *end example*]

If a substitution results in an invalid type or expression, type deduction fails.

An
invalid type or expression is one that would be ill-formed, with a diagnostic
required, if written in the same context using the substituted arguments.

Invalid types and expressions can result in a deduction failure
only in the immediate context of the deduction substitution loci.

[*Note 6*: *end note*]

The substitution into types and expressions can result
in effects such as the instantiation of class template specializations and/or
function template specializations, the generation of implicitly-defined functions,
etc.

Such effects are not in the “immediate context” and can result in the
program being ill-formed.

— A *lambda-expression* appearing in a function type
or a template parameter is not considered part of the immediate context
for the purposes of template argument deduction.

[*Note 7*: — *end note*]

The intent is to avoid requiring implementations to deal with
substitution failure involving arbitrary statements.

[*Example 7*: template <class T>
auto f(T) -> decltype([]() { T::invalid; } ());
void f(...);
f(0); // error: invalid expression not part of the immediate context
template <class T, std::size_t = sizeof([]() { T::invalid; })>
void g(T);
void g(...);
g(0); // error: invalid expression not part of the immediate context
template <class T>
auto h(T) -> decltype([x = T::invalid]() { });
void h(...);
h(0); // error: invalid expression not part of the immediate context
template <class T>
auto i(T) -> decltype([]() -> typename T::invalid { });
void i(...);
i(0); // error: invalid expression not part of the immediate context
template <class T>
auto j(T t) -> decltype([](auto x) -> decltype(x.invalid) { } (t)); // #1
void j(...); // #2
j(0); // deduction fails on #1, calls #2
— *end example*]

[*Example 8*: struct X { };
struct Y {
Y(X) {}
};
template <class T> auto f(T t1, T t2) -> decltype(t1 + t2); // #1
X f(Y, Y); // #2
X x1, x2;
X x3 = f(x1, x2); // deduction fails on #1 (cannot add X+X), calls #2
— *end example*]

[*Note 8*: *end note*]

Type deduction can fail for the following reasons:

— - Attempting to instantiate a pack expansion containing multiple packs of differing lengths.
- Attempting to use a type in a
*nested-name-specifier*of a*qualified-id*when that type does not contain the specified member, or- the specified member is not a type where a type is required, or
- the specified member is not a template where a template is required, or
- the specified member is not a non-type where a non-type is required.

[*Example 11*: template <int I> struct X { }; template <template <class T> class> struct Z { }; template <class T> void f(typename T::Y*) {} template <class T> void g(X<T::N>*) {} template <class T> void h(Z<T::TT>*) {} struct A {}; struct B { int Y; }; struct C { typedef int N; }; struct D { typedef int TT; }; int main() { // Deduction fails in each of these cases: f<A>(0); // A does not contain a member Y f<B>(0); // The Y member of B is not a type g<C>(0); // The N member of C is not a non-type h<D>(0); // The TT member of D is not a template } —*end example*] - Attempting to create a pointer to reference type.
- Attempting to create a reference to void.
- Attempting to create a function type in which a parameter has a type of void, or in which the return type is a function type or array type.

[*Example 15*:

In the following example,
assuming a signed char
cannot represent the value 1000,
a narrowing conversion
would be required
to convert the *template-argument*
of type int to signed char,
therefore substitution fails for the
second template ([temp.arg.nontype]).

template <int> int f(int);
template <signed char> int f(int);
int i1 = f<1000>(0); // OK
int i2 = f<1>(0); // ambiguous; not narrowing
— *end example*]

Template argument deduction is done by comparing each function
template parameter type (call it
P)
that contains *template-parameter**s* that participate in template argument deduction
with the type of the corresponding argument of the call (call it
A)
as described below.

If removing references and cv-qualifiers from P gives
or
for some and N and the
argument is a non-empty initializer list ([dcl.init.list]), then deduction is
performed instead for each element of the initializer list independently,
taking
as separate function template parameter types
and the initializer element as the corresponding argument.

In the case, if N is a non-type template parameter,
N is deduced from the length of the initializer list.

Otherwise, an initializer list argument causes the
parameter to be considered a non-deduced context ([temp.deduct.type]).

[*Example 1*: template<class T> void f(std::initializer_list<T>);
f({1,2,3}); // T deduced as int
f({1,"asdf"}); // error: T deduced as both int and const char*
template<class T> void g(T);
g({1,2,3}); // error: no argument deduced for T
template<class T, int N> void h(T const(&)[N]);
h({1,2,3}); // T deduced as int; N deduced as 3
template<class T> void j(T const(&)[3]);
j({42}); // T deduced as int; array bound not considered
struct Aggr { int i; int j; };
template<int N> void k(Aggr const(&)[N]);
k({1,2,3}); // error: deduction fails, no conversion from int to Aggr
k({{1},{2},{3}}); // OK, N deduced as 3
template<int M, int N> void m(int const(&)[M][N]);
m({{1,2},{3,4}}); // M and N both deduced as 2
template<class T, int N> void n(T const(&)[N], T);
n({{1},{2},{3}},Aggr()); // OK, T is Aggr, N is 3
template<typename T, int N> void o(T (* const (&)[N])(T)) { }
int f1(int);
int f4(int);
char f4(char);
o({ &f1, &f4 }); // OK, T deduced as int from first element, nothing
// deduced from second element, N deduced as 2
o({ &f1, static_cast<char(*)(char)>(&f4) }); // error: conflicting deductions for T
— *end example*]

For a function parameter pack that occurs at the end
of the *parameter-declaration-list*,
deduction is performed for each remaining argument of the call,
taking the type P
of the *declarator-id* of the function parameter pack
as the corresponding function template parameter type.

Each deduction deduces template arguments for subsequent positions in
the template parameter packs expanded by the function parameter pack.

When a function parameter pack appears in a non-deduced
context ([temp.deduct.type]), the type of that pack is
never deduced.

[*Example 2*: template<class ... Types> void f(Types& ...);
template<class T1, class ... Types> void g(T1, Types ...);
template<class T1, class ... Types> void g1(Types ..., T1);
void h(int x, float& y) {
const int z = x;
f(x, y, z); // Types deduced as int, float, const int
g(x, y, z); // T1 deduced as int; Types deduced as float, int
g1(x, y, z); // error: Types is not deduced
g1<int, int, int>(x, y, z); // OK, no deduction occurs
}
— *end example*]

If
P
is not a reference type:

- If A is an array type, the pointer type produced by the array-to-pointer standard conversion is used in place of A for type deduction; otherwise,
- If A is a function type, the pointer type produced by the function-to-pointer standard conversion is used in place of A for type deduction; otherwise,
- If A is a cv-qualified type, the top-level cv-qualifiers of A's type are ignored for type deduction.

If
P
is a cv-qualified type, the top-level cv-qualifiers of
P's
type are ignored for type deduction.

[*Example 3*: template<class T> int f(const T&);
int n1 = f(5); // calls f<int>(const int&)
const int i = 0;
int n2 = f(i); // calls f<int>(const int&)
template <class T> int g(volatile T&);
int n3 = g(i); // calls g<const int>(const volatile int&)
— *end example*]

A *forwarding reference*
is an rvalue reference to a cv-unqualified template parameter
that does not represent a template parameter of a class template
(during class template argument deduction ([over.match.class.deduct])).

If P is a forwarding reference and the argument is an
lvalue, the type “lvalue reference to A” is used in place of A for type
deduction.

[*Example 4*: template <class T> int f(T&& heisenreference);
template <class T> int g(const T&&);
int i;
int n1 = f(i); // calls f<int&>(int&)
int n2 = f(0); // calls f<int>(int&&)
int n3 = g(i); // error: would call g<int>(const int&&), which
// would bind an rvalue reference to an lvalue
template <class T> struct A {
template <class U>
A(T&&, U&&, int*); // #1: T&& is not a forwarding reference.
// U&& is a forwarding reference.
A(T&&, int*); // #2
};
template <class T> A(T&&, int*) -> A<T>; // #3: T&& is a forwarding reference.
int *ip;
A a{i, 0, ip}; // error: cannot deduce from #1
A a0{0, 0, ip}; // uses #1 to deduce A<int> and #1 to initialize
A a2{i, ip}; // uses #3 to deduce A<int&> and #2 to initialize
— *end example*]

In general, the deduction process attempts to find template argument
values that will make the deduced
A
identical to
A
(after
the type
A
is transformed as described above).

However, there are
three cases that allow a difference:

- If the original P is a reference type, the deduced A (i.e., the type referred to by the reference) can be more cv-qualified than the transformed A.
- The transformed A can be another pointer or pointer-to-member type that can be converted to the deduced A via a function pointer conversion and/or qualification conversion.
- If P is a class and P has the form
*simple-template-id*, then the transformed A can be a derived class D of the deduced A.Likewise, if P is a pointer to a class of the form*simple-template-id*, the transformed A can be a pointer to a derived class D pointed to by the deduced A.However, if there is a class C that is a (direct or indirect) base class of D and derived (directly or indirectly) from a class B and that would be a valid deduced A, the deduced A cannot be B or pointer to B, respectively.[*Example 5*: template <typename... T> struct X; template <> struct X<> {}; template <typename T, typename... Ts> struct X<T, Ts...> : X<Ts...> {}; struct D : X<int> {}; struct E : X<>, X<int> {}; template <typename... T> int f(const X<T...>&); int x = f(D()); // calls f<int>, not f<> // B is X<>, C is X<int> int z = f(E()); // calls f<int>, not f<> —*end example*]

These alternatives are considered only if type deduction would
otherwise fail.

If they yield more than one possible deduced
A,
the type deduction fails.

[*Note 1*: *end note*]

If a
*template-parameter*
is not used in any of the function parameters of a function template,
or is used only in a non-deduced context, its corresponding
*template-argument*
cannot be deduced from a function call and the
*template-argument*
must be explicitly specified.

— When
P
is a function type, function pointer type, or pointer-to-member-function type:

- If the argument is an overload set containing one or more function templates, the parameter is treated as a non-deduced context.
- If the argument is an overload set (not containing function templates), trial argument deduction is attempted using each of the members of the set.If deduction succeeds for only one of the overload set members, that member is used as the argument value for the deduction.If deduction succeeds for more than one member of the overload set the parameter is treated as a non-deduced context.

[*Example 6*: // Only one function of an overload set matches the call so the function parameter is a deduced context.
template <class T> int f(T (*p)(T));
int g(int);
int g(char);
int i = f(g); // calls f(int (*)(int))
— *end example*]

[*Example 7*: // Ambiguous deduction causes the second function parameter to be a non-deduced context.
template <class T> int f(T, T (*p)(T));
int g(int);
char g(char);
int i = f(1, g); // calls f(int, int (*)(int))
— *end example*]

Template arguments can be deduced from the type specified when taking
the address of an overload set.

If there is a target,
the function template's function type and the target type
are used as the types of
P
and
A,
and the deduction is done as
described in [temp.deduct.type].

A placeholder type in the return type of a
function template is a non-deduced context.

If template argument
deduction succeeds for such a function, the return type is determined
from instantiation of the function body.

Template argument deduction is done by comparing the return type of
the
conversion function template
(call it
P)
with the type specified by the *conversion-type-id* of the
*conversion-function-id* being looked up
(call it A) as described in [temp.deduct.type].

If the *conversion-function-id* is constructed during
overload resolution ([over.match.funcs]),
the rules in the remainder of this subclause apply.

If P is a reference type, the type referred to by P is used in place
of P for type deduction and for any further references to or transformations of
P in the remainder of this subclause.

If
A
is not a reference type:

- If P is an array type, the pointer type produced by the array-to-pointer standard conversion is used in place of P for type deduction; otherwise,
- If P is a function type, the pointer type produced by the function-to-pointer standard conversion is used in place of P for type deduction; otherwise,
- If P is a cv-qualified type, the top-level cv-qualifiers of P's type are ignored for type deduction.

In general, the deduction process attempts to find template argument
values that will make the deduced
A
identical to
A.

However, certain attributes of A may be ignored:

- If the original A is a reference type, any cv-qualifiers of A (i.e., the type referred to by the reference).
- If the original A is a function pointer or pointer-to-member-function type with a potentially-throwing exception specification ([except.spec]), the exception specification.
- Any cv-qualifiers in A that can be restored by a qualification conversion.

These attributes are ignored only if type deduction would
otherwise fail.

If ignoring them allows more than one possible deduced
A,
the type deduction fails.

Template argument deduction is done by comparing certain types associated with
the two function templates being compared.

Two sets of types are used to determine the partial ordering.

For each of
the templates involved there is the original function type and the
transformed function type.

The deduction process uses the
transformed type as the argument template and the original type of the
other template as the parameter template.

This process is done twice
for each type involved in the partial ordering comparison: once using
the transformed template-1 as the argument template and template-2 as
the parameter template and again using the transformed template-2 as
the argument template and template-1 as the parameter template.

The types used to determine the ordering depend on the context in which
the partial ordering is done:

- In the context of a call to a conversion function, the return types of the conversion function templates are used.
- In other contexts the function template's function type is used.

Each type nominated above from the parameter template and the corresponding type from the
argument template are used as the types of
P
and
A.

If both
P
and
A
were reference types (before being replaced with the type referred to
above), determine which of the two types (if any) is more cv-qualified
than the other; otherwise the types are considered to be equally
cv-qualified for partial ordering purposes.

The result of this
determination will be used below.

If P is a function parameter pack, the type A of each remaining
parameter type of the argument template is compared with the type P of
the *declarator-id* of the function parameter pack.

Each comparison
deduces template arguments for subsequent positions in the template parameter
packs expanded by the function parameter pack.

Similarly, if A was transformed from a function parameter pack,
it is compared with each remaining parameter type of the parameter template.

If deduction succeeds for a given type,
the type from the argument template is considered to be at least as specialized
as the type from the parameter template.

[*Example 1*: template<class... Args> void f(Args... args); // #1
template<class T1, class... Args> void f(T1 a1, Args... args); // #2
template<class T1, class T2> void f(T1 a1, T2 a2); // #3
f(); // calls #1
f(1, 2, 3); // calls #2
f(1, 2); // calls #3; non-variadic template #3 is more specialized
// than the variadic templates #1 and #2
— *end example*]

If, for a given type, the
types are identical after the transformations above
and both P and A were reference types (before being replaced with the
type referred to above):

- if the type from the argument template was an lvalue reference and the type from the parameter template was not, the parameter type is not considered to be at least as specialized as the argument type; otherwise,
- if the type from the argument template is more cv-qualified than the type from the parameter template (as described above), the parameter type is not considered to be at least as specialized as the argument type.

Function template F
is *at least as specialized as*
function template G if,
for each pair of types used to determine the ordering,
the type from F
is at least as specialized as
the type from G.

F
is *more specialized than*
G if
F
is at least as specialized as
G and
G
is not at least as specialized as
F.

If, after considering the above, function template F
is at least as specialized as function template G and vice-versa, and
if G has a trailing function parameter pack
for which F does not have a corresponding parameter, and
if F does not have a trailing function parameter pack,
then F is more specialized than G.

In most cases,
deduction fails if not all template parameters have values,
but for partial ordering purposes a template
parameter may remain without a value provided it is not used in the
types being used for partial ordering.

[*Example 2*: template <class T> T f(int); // #1
template <class T, class U> T f(U); // #2
void g() {
f<int>(1); // calls #1
}
— *end example*]

[*Example 3*: template<class ...> struct Tuple { };
template<class ... Types> void g(Tuple<Types ...>); // #1
template<class T1, class ... Types> void g(Tuple<T1, Types ...>); // #2
template<class T1, class ... Types> void g(Tuple<T1, Types& ...>); // #3
g(Tuple<>()); // calls #1
g(Tuple<int, float>()); // calls #2
g(Tuple<int, float&>()); // calls #3
g(Tuple<int>()); // calls #3
— *end example*]

Template arguments can be deduced in several different contexts, but
in each case a type that is specified in terms of template parameters
(call it
P)
is compared with an actual type (call it
A),
and an attempt is made to find template argument values (a type for a type
parameter, a value for a non-type parameter, or a template for a
template parameter) that will make
P,
after substitution of the deduced values (call it the deduced
A),
compatible with
A.

In some cases, the deduction is done using a single set of types
P
and
A,
in other cases, there will be a set of corresponding types
P
and
A.

Type deduction is done
independently for each
P/A
pair, and the deduced template
argument values are then combined.

If type deduction cannot be done
for any
P/A
pair, or if for any pair the deduction leads to more than
one possible set of deduced values, or if different pairs yield
different deduced values, or if any template argument remains neither
deduced nor explicitly specified, template argument deduction fails.

The type of a type parameter
is only deduced from an array bound
if it is not otherwise deduced.

A given type
P
can be composed from a number of other
types, templates, and non-type values:

- A function type includes the types of each of the function parameters, the return type, and its exception specification.
- A pointer-to-member type includes the type of the class object pointed to and the type of the member pointed to.
- A type that is a specialization of a class template (e.g., A<int>) includes the types, templates, and non-type values referenced by the template argument list of the specialization.
- An array type includes the array element type and the value of the array bound.

In most cases, the types, templates, and non-type values that are used
to compose
P
participate in template argument deduction.

That is,
they may be used to determine the value of a template argument, and
template argument deduction fails if
the value so determined is not consistent with the values determined
elsewhere.

In certain contexts, however, the value does not
participate in type deduction, but instead uses the values of template
arguments that were either deduced elsewhere or explicitly specified.

If a template parameter is used only in non-deduced contexts and is not
explicitly specified, template argument deduction fails.

[*Note 1*: *end note*]

Under [temp.deduct.call],
if P contains no *template-parameter**s* that appear
in deduced contexts, no deduction is done, so P and A
need not have the same form.

— The non-deduced contexts are:

- A non-type template argument or an array bound in which a subexpression references a template parameter.
- A template parameter used in the parameter type of a function parameter that has a default argument that is being used in the call for which argument deduction is being done.
- A function parameter for which the associated argument is an overload set ([over.over]), and one or more of the following apply:
- more than one function matches the function parameter type (resulting in an ambiguous deduction), or
- no function matches the function parameter type, or
- the overload set supplied as an argument contains one or more function templates.

- A function parameter for which the associated argument is an initializer list ([dcl.init.list]) but the parameter does not have a type for which deduction from an initializer list is specified ([temp.deduct.call]).[
*Example 1*: template<class T> void g(T); g({1,2,3}); // error: no argument deduced for T —*end example*] - A function parameter pack that does not occur at the end of the
*parameter-declaration-list*.

When a type name is specified in a way that includes a non-deduced
context, all of the types that comprise that type name are also
non-deduced.

However, a compound type can include both deduced and non-deduced types.

[*Example 3*:

Here is an example in which different parameter/argument pairs produce
inconsistent template argument deductions:
template<class T> void f(T x, T y) { /* ... */ }
struct A { /* ... */ };
struct B : A { /* ... */ };
void g(A a, B b) {
f(a,b); // error: T deduced as both A and B
f(b,a); // error: T deduced as both A and B
f(a,a); // OK, T is A
f(b,b); // OK, T is B
}

Here is an example where two template arguments are deduced from a
single function parameter/argument pair.

This can lead to conflicts
that cause type deduction to fail:
template <class T, class U> void f( T (*)( T, U, U ) );
int g1( int, float, float);
char g2( int, float, float);
int g3( int, char, float);
void r() {
f(g1); // OK, T is int and U is float
f(g2); // error: T deduced as both char and int
f(g3); // error: U deduced as both char and float
}

Here is an example where the exception specification of a function type
is deduced:
template<bool E> void f1(void (*)() noexcept(E));
template<bool> struct A { };
template<bool B> void f2(void (*)(A<B>) noexcept(B));
void g1();
void g2() noexcept;
void g3(A<true>);
void h() {
f1(g1); // OK, E is false
f1(g2); // OK, E is true
f2(g3); // error: B deduced as both true and false
}

Here is an example where a qualification conversion applies between the
argument type on the function call and the deduced template argument type:
template<class T> void f(const T*) { }
int* p;
void s() {
f(p); // f(const int*)
}

Here is an example where the template argument is used to instantiate
a derived class type of the corresponding function parameter type:
template <class T> struct B { };
template <class T> struct D : public B<T> {};
struct D2 : public B<int> {};
template <class T> void f(B<T>&) {}
void t() {
D<int> d;
D2 d2;
f(d); // calls f(B<int>&)
f(d2); // calls f(B<int>&)
}

— A template type argument
T,
a template template argument
TT,
or a template non-type argument
i
can be deduced if
P
and
A
have one of the following forms:
cv T
T*
T&
T&&
T[i]
T(T) noexcept(i)
T T::*
TT<T>
TT<i>
TT<TT>
TT<>
where

- T represents a type or parameter-type-list that either satisfies these rules recursively, is a non-deduced context in P or A, or is the same non-dependent type in P and A,
- TT represents either a class template or a template template parameter,
- i represents an expression that either is an i, is value-dependent in P or A, or has the same constant value in P and A, and
- noexcept(i) represents an
exception specification ([except.spec])
in which the (possibly-implicit, see [dcl.fct])
*noexcept-specifier*'s operand satisfies the rules for an i above.

Similarly,
<T>
represents template argument lists where at least one argument contains a
T,
<i>
represents template argument lists where at least one argument contains an
i
and
<>
represents template argument lists where no argument contains a
T
or an
i.

If P has a form that contains <T>
or <i>, then each argument of the
respective template argument list of P is compared with the
corresponding argument of the corresponding
template argument list of A.

If the template argument list
of P contains a pack expansion that is not the last
template argument, the entire template argument list is a non-deduced
context.

If is a pack expansion, then the pattern
of is compared with each remaining argument in the
template argument list of A.

Each comparison deduces
template arguments for subsequent positions in the template parameter
packs expanded by .

During partial ordering, if was
originally a pack expansion:

- if P does not contain a template argument corresponding to then is ignored;
- otherwise, if is not a pack expansion, template argument deduction fails.

[*Example 4*: template<class T1, class... Z> class S; // #1
template<class T1, class... Z> class S<T1, const Z&...> { }; // #2
template<class T1, class T2> class S<T1, const T2&> { }; // #3
S<int, const int&> s; // both #2 and #3 match; #3 is more specialized
template<class T, class... U> struct A { }; // #1
template<class T1, class T2, class... U> struct A<T1, T2*, U...> { }; // #2
template<class T1, class T2> struct A<T1, T2> { }; // #3
template struct A<int, int*>; // selects #2
— *end example*]

Similarly, if P has a form that contains
(T), then each parameter type
of the respective parameter-type-list ([dcl.fct]) of
P is compared with the corresponding parameter type
of the corresponding parameter-type-list
of A.

If P and A are function types that originated from deduction when
taking the address of a function template ([temp.deduct.funcaddr]) or when
deducing template arguments from a function declaration ([temp.deduct.decl])
and and are parameters of the top-level
parameter-type-list of P and A, respectively,
is adjusted if it is a forwarding reference ([temp.deduct.call])
and is an lvalue reference, in which case the type of
is changed to be the template parameter type (i.e., T&& is
changed to simply T).

[*Example 5*: template <class T> void f(T&&);
template <> void f(int&) { } // #1
template <> void f(int&&) { } // #2
void g(int i) {
f(i); // calls f<int&>(int&), i.e., #1
f(0); // calls f<int>(int&&), i.e., #2
}
— *end example*]

If the *parameter-declaration*
corresponding to is a function parameter pack,
then the type of its *declarator-id* is compared with
each remaining parameter type in the parameter-type-list
of A.

Each comparison deduces template arguments for
subsequent positions in the template parameter packs expanded by the
function parameter pack.

During partial ordering, if was
originally a function parameter pack:

- if P does not contain a function parameter type corresponding to then is ignored;
- otherwise, if is not a function parameter pack, template argument deduction fails.

[*Example 6*: template<class T, class... U> void f(T*, U...) { } // #1
template<class T> void f(T) { } // #2
template void f(int*); // selects #1
— *end example*]

These forms can be used in the same way as
T
is for further composition of types.

[*Example 7*: *end example*]

X<int> (*)(char[6])
is of the form
*template-name*<T> (*)(*type*[i])
which is a variant of
*type* (*)(T)
where type is
X<int>
and
T
is
char[6].

— Template arguments cannot be deduced from function arguments involving
constructs other than the ones specified above.

When the value of the argument
corresponding to a non-type template parameter P
that is declared with a dependent type
is deduced from an expression,
the template parameters in the type of P
are deduced from the type of the value.

[*Example 8*: template<long n> struct A { };
template<typename T> struct C;
template<typename T, T n> struct C<A<n>> {
using Q = T;
};
using R = long;
using R = C<A<2>>::Q; // OK; T was deduced as long from the
// template argument value in the type A<2>
— *end example*]

[*Example 10*: template<bool> struct A { };
template<auto> struct B;
template<auto X, void (*F)() noexcept(X)> struct B<F> {
A<X> ax;
};
void f_nothrow() noexcept;
B<f_nothrow> bn; // OK, type of X deduced as bool
— *end example*]

[*Example 11*: template<class T, T i> void f(int (&a)[i]);
int v[10];
void g() {
f(v); // OK, T is std::size_t
}
— *end example*]

[*Note 4*: *end note*]

Except for reference and pointer types, a major array bound is not part of a
function parameter type and cannot be deduced from an argument:
template<int i> void f1(int a[10][i]);
template<int i> void f2(int a[i][20]);
template<int i> void f3(int (&a)[i][20]);
void g() {
int v[10][20];
f1(v); // OK, i deduced as 20
f1<20>(v); // OK
f2(v); // error: cannot deduce template-argument i
f2<10>(v); // OK
f3(v); // OK, i deduced as 10
}

— [*Note 5*: — *end note*]

If, in the declaration of a function template with a non-type
template parameter, the non-type template parameter
is used in a subexpression in the function parameter list,
the expression is a non-deduced context as specified above.

[*Example 12*: template <int i> class A { /* ... */ };
template <int i> void g(A<i+1>);
template <int i> void f(A<i>, A<i+1>);
void k() {
A<1> a1;
A<2> a2;
g(a1); // error: deduction fails for expression i+1
g<0>(a1); // OK
f(a1, a2); // OK
}
— *end example*]

[*Note 6*:

Template parameters do not participate in template argument deduction if
they are used only in non-deduced contexts.

For example,

template<int i, typename T>
T deduce(typename A<T>::X x, // T is not deduced here
T t, // but T is deduced here
typename B<i>::Y y); // i is not deduced here
A<int> a;
B<77> b;
int x = deduce<77>(a.xm, 62, b.ym);
// T deduced as int; a.xm must be convertible to A<int>::X
// i is explicitly specified to be 77; b.ym must be convertible to B<77>::Y
— *end note*]

If P has a form that contains <i>, and
if the type of i differs from the type
of the corresponding template parameter
of the template named by the enclosing *simple-template-id*,
deduction fails.

If P has a form that contains [i], and if the type of
i is not an integral type, deduction fails.128

[*Example 13*: template<int i> class A { /* ... */ };
template<short s> void f(A<s>);
void k1() {
A<1> a;
f(a); // error: deduction fails for conversion from int to short
f<1>(a); // OK
}
template<const short cs> class B { };
template<short s> void g(B<s>);
void k2() {
B<1> b;
g(b); // OK, cv-qualifiers are ignored on template parameter types
}
— *end example*]

A
*template-argument*
can be deduced from a function, pointer to function, or
pointer-to-member-function type.

[*Example 14*: template<class T> void f(void(*)(T,int));
template<class T> void foo(T,int);
void g(int,int);
void g(char,int);
void h(int,int,int);
void h(char,int);
int m() {
f(&g); // error: ambiguous
f(&h); // OK, void h(char,int) is a unique match
f(&foo); // error: type deduction fails because foo is a template
}
— *end example*]

A template
*type-parameter*
cannot be deduced from the type of a function default argument.

[*Example 15*: template <class T> void f(T = 5, T = 7);
void g() {
f(1); // OK, calls f<int>(1,7)
f(); // error: cannot deduce T
f<int>(); // OK, calls f<int>(5,7)
}
— *end example*]

The
*template-argument*
corresponding to a template
*template-parameter*
is deduced from the type of the
*template-argument*
of a class template specialization used in the argument list of a function call.

[*Example 16*: template <template <class T> class X> struct A { };
template <template <class T> class X> void f(A<X>) { }
template<class T> struct B { };
A<B> ab;
f(ab); // calls f(A<B>)
— *end example*]

[*Note 7*: *end note*]

Template argument deduction involving parameter
packs ([temp.variadic]) can deduce zero or more arguments for
each parameter pack.

— [*Example 17*: template<class> struct X { };
template<class R, class ... ArgTypes> struct X<R(int, ArgTypes ...)> { };
template<class ... Types> struct Y { };
template<class T, class ... Types> struct Y<T, Types& ...> { };
template<class ... Types> int f(void (*)(Types ...));
void g(int, float);
X<int> x1; // uses primary template
X<int(int, float, double)> x2; // uses partial specialization; ArgTypes contains float, double
X<int(float, int)> x3; // uses primary template
Y<> y1; // uses primary template; Types is empty
Y<int&, float&, double&> y2; // uses partial specialization; T is int&, Types contains float, double
Y<int, float, double> y3; // uses primary template; Types contains int, float, double
int fv = f(g); // OK; Types contains int, float
— *end example*]

128)128)

Although the
*template-argument*
corresponding to a
*template-parameter*
of type
bool
can be deduced from an array bound, the resulting value will always be
true
because the array bound will be nonzero.

In a declaration whose *declarator-id* refers to a specialization
of a function template, template argument deduction is performed to identify
the specialization to which the declaration refers.

Specifically, this is done
for explicit instantiations, explicit specializations,
and certain friend declarations.

This is also done to
determine whether a deallocation function template specialization matches a placement
operator new ([basic.stc.dynamic.deallocation], [expr.new]).

In all these cases, P is the type of the function template being considered
as a potential match and A is either the function type from the
declaration
or the type of the deallocation function that would match the placement
operator new as described in [expr.new].

The
deduction is done as described in [temp.deduct.type].

If, for the set of function templates so considered, there is either no match or
more than one match after partial ordering has been considered ([temp.func.order]),
deduction fails and, in the declaration cases, the
program is ill-formed.