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>
.