I understand that, given a braced initializer, auto will deduce a type of std::initializer_list, while template type deduction will fail:
The reason is described in N2640:
A {}-list cannot deduce against a plain type parameter
T. For example:templatevoid count(T); // (1). struct Dimensions { Dimensions(int, int); }; size_t count(Dimensions); // (2). size_t n = count({1, 2}); // Calls (2); deduction doesn't // succeed for (1). Another example:
templatevoid inc(T, int); // (1) template void inc(std::initializer_list , long); // (2) inc({1, 2, 3}, 3); // Calls (2). (If deduction had succeeded // for (1), (1) would have been called — a // surprise.) On the other hand, being able to deduce an
initializer_listforTis attractive to allow:auto x = { 1, 1, 2, 3, 5 }; f(x); g(x);which was deemed desirable behavior since the very beginning of the EWG discussions about initializer lists.
Rather than coming up with a clever deduction rule for a parameter type
Tmatched with a {}-list (an option we pursued in earlier sketches and drafts of this paper), we now prefer to handle this with a special case for "auto" variable deduction when the initializer is a {}-list. I.e., for the specific case of a variable declared with an "auto" type specifier and a {}-list initializer, the "auto" is deduced as for a functionf(initializer_listinstead of as for a function) f(T).
For conclusion, the problem is that if we allow a {}-list to deduce against a plain type parameter T, then the function with parameter T would have very high priority during overload resolution, which may cause wired behavior (like the examples above).