I posted a way that seemed to work but unfortunately caused memory access violations because of how initializer_lists are treated as references to locally-scoped copies of values.
Here's an alternative. A separate function and a separate static initializer list is generated for each possible number of items, which are counted with a parameter pack. This is not thread safe and uses a const_cast (which is considered very bad) to write into the static initializer_list memory. However, it works cleanly in both gcc and clang.
If for some obscure reason you need this problem solved and have no other options, you could try this hack.
#include <initializer_list>
#include <iostream>
#include <stdexcept>
#include <type_traits>
#include <vector>
namespace __range_to_initializer_list {
constexpr size_t DEFAULT_MAX_LENGTH = 128;
template <typename V> struct backingValue { static V value; };
template <typename V> V backingValue<V>::value;
template <typename V, typename... Vcount> struct backingList { static std::initializer_list<V> list; };
template <typename V, typename... Vcount>
std::initializer_list<V> backingList<V, Vcount...>::list = {(Vcount)backingValue<V>::value...};
template <size_t maxLength, typename It, typename V = typename It::value_type, typename... Vcount>
static typename std::enable_if< sizeof...(Vcount) >= maxLength,
std::initializer_list<V> >::type generate_n(It begin, It end, It current)
{
throw std::length_error("More than maxLength elements in range.");
}
template <size_t maxLength = DEFAULT_MAX_LENGTH, typename It, typename V = typename It::value_type, typename... Vcount>
static typename std::enable_if< sizeof...(Vcount) < maxLength,
std::initializer_list<V> >::type generate_n(It begin, It end, It current)
{
if (current != end)
return generate_n<maxLength, It, V, V, Vcount...>(begin, end, ++current);
current = begin;
for (auto it = backingList<V,Vcount...>::list.begin();
it != backingList<V,Vcount...>::list.end();
++current, ++it)
*const_cast<V*>(&*it) = *current;
return backingList<V,Vcount...>::list;
}
}
template <typename It>
std::initializer_list<typename It::value_type> range_to_initializer_list(It begin, It end)
{
return __range_to_initializer_list::generate_n(begin, end, begin);
}
int main()
{
std::vector<int> vec = {1,2,3,4,5,6,7,8,9,10};
std::initializer_list<int> list = range_to_initializer_list(vec.begin(), vec.end());
for (int i : list)
std::cout << i << std::endl;
return 0;
}