Nope. Constructing an initializer list requires a compile-time known length, and consuming an initializer list you do not have a compile-time known length.
initializer lists are intended for "user-facing" operations, where the user is the consumer of your interface. Using them internally like that doesn't work well.
An approach you can use is to write an array_view<T> type that wraps a range of contiguous memory (an initializer list, a vector, a std array, or a C array are all examples of this) in a range-view like way (with begin, end, data, size, empty, front, back methods. Iterators are pointers).
Then give it implicit converting ctors from vector<T>&, vector<std::remove_const_t<T>> const&, initializer_list<std::remove_const_t<T>> etc.
void boo(array_view<const unsigned> l)
{
}
template <class T>
void foo(std::initializer_list<T> l)
{
boo(std::vector<unsigned>{l.begin(), l.end()});
}
goes an reallocates a new buffer of unsigned values based off whatever was in l and passes it to boo. boo consumes an array_view<unsigned const>, which can convert from a vector or an initializer_list of unsigned.
We can then write maybe_convert_list:
template <class T, class U, class...LowPrecidence>
std::vector<T> maybe_convert_list(std::initializer_list<U> l, LowPrecidence&&...)
{
return {l.begin(), l.end()};
}
template <class T>
std::initializer_list<T> maybe_convert_list(std::initializer_list<T> l)
{
return l;
}
template <class T>
void foo(std::initializer_list<T> l)
{
boo(maybe_convert_list<unsigned>(l));
}
or somesuch. It leaves initializer_list<unsigned> alone. For other types of lists, it converts it to a std::vector<unsigned>.