SFINAE only works on template parameter subsitution(hence the S in SFINAE). The following works:
template<typename T>
struct holder {
T t_;
holder() :
t_() {}
template<typename U = T>
holder(typename std::enable_if<std::is_constructible<U, std::initializer_list<typename U::value_type>>::value,
std::initializer_list<typename U::value_type>>::type values)
: t_(values) {}
};
If you didn't use a template function, then the whole class would be instantiated for the type int
(in your example), leading to a compiler error.
Note that you could make the function signature nicer if you used an extra template parameter:
template<typename U = T, class = typename std::enable_if<std::is_constructible<U, std::initializer_list<typename U::value_type>>::value, bool>::type>
holder(std::initializer_list<typename U::value_type> values)
: t_(values) {}