Template argument deduction is done by comparing each function
template parameter type (call it
P)
that contains
template-parameters 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
std::initializer_list<P′>
or
P′[N]
for some
P′ 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
P′
as separate function template parameter types
P′i
and the
ith initializer element as the corresponding argument
. In the
P′[N] 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});
f({1,"asdf"});
template<class T> void g(T);
g({1,2,3});
template<class T, int N> void h(T const(&)[N]);
h({1,2,3});
template<class T> void j(T const(&)[3]);
j({42});
struct Aggr { int i; int j; };
template<int N> void k(Aggr const(&)[N]);
k({1,2,3});
k({{1},{2},{3}});
template<int M, int N> void m(int const(&)[M][N]);
m({{1,2},{3,4}});
template<class T, int N> void n(T const(&)[N], T);
n({{1},{2},{3}},Aggr());
template<typename T, int N> void o(T (* const (&)[N])(T)) { }
int f1(int);
int f4(int);
char f4(char);
o({ &f1, &f4 });
o({ &f1, static_cast<char(*)(char)>(&f4) });
—
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);
g(x, y, z);
g1(x, y, z);
g1<int, int, int>(x, y, z);
}
—
end example]