CWG Issue 1591 (original) (raw)
Template argument deduction is done by comparing each function template parameter type (call it P) with the type of the corresponding argument of the call (call it A) as described below. If P is a dependent type, removing references and cv-qualifiers from Pgives std::initializer_list<_P'_> or_P'_[_N_] for some P' and N, and the argument is an a non-empty initializer list (9.5.5 [dcl.init.list]), then deduction is performed instead for each element of the initializer list, taking P' as a function template parameter type and the initializer element as its argument, and 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 (13.10.3.6 [temp.deduct.type]). [Example:
template void f(std::initializer_list); f({1,2,3}); // T deduced to int f({1,"asdf"}); // error: T deduced to both int and const char*
template 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 to int, N deduced to 3
template void j(T const(&)[3]); j({42}); // T deduced to int, array bound not considered
struct Aggr { int i; int j; }; template 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 to 3
template<int M, int N> void m(int const(&)[M][N]); m({{1,2},{3,4}}); // M and N both deduced to 2
template<class T, int N> void n(T const(&)[N], T); n({{1},{2},{3}},Aggr()); // OK, T is Aggr, N is 3
—_end example_] For a function parameter pack...