#include
#include
void foo(std::initializer_list>) {}
List initialization relies on knowing what type is being initialized. {1} could mean many things. When applied to an int, it fills it with a 1. When applied to a std::vector, it means to create a one-element vector, with 1 in the first element. And so on.
When you call a template function who's type is completely unconstrained, then there is no type information for list initialization to work with. And without type information, list initialization cannot work.
For example:
bar({{0,1}});
You expect this to be of the type std::initializer_list. But how could the compiler know that? bar's first parameter is an unconstrained template; it can literally be any type. How could the compiler possibly guess that you meant this specific type?
Quite simply, it can't. Compilers are good, but they're not clairvoyant. List initialization can only work in the presence of type information, and unconstrained templates remove all of that.
By all rights, that line should have failed to compile, according to C++11. It cannot deduce what type you intended the {...} to be, so it should have failed. That looks like a GCC bug or something.