Everyone creates std::vector from std::initializer_list, but what about the other way around?
eg. if you use a std::initializer_list
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
#include
#include
#include
#include
namespace __range_to_initializer_list {
constexpr size_t DEFAULT_MAX_LENGTH = 128;
template struct backingValue { static V value; };
template V backingValue::value;
template struct backingList { static std::initializer_list list; };
template
std::initializer_list backingList::list = {(Vcount)backingValue::value...};
template
static typename std::enable_if< sizeof...(Vcount) >= maxLength,
std::initializer_list >::type generate_n(It begin, It end, It current)
{
throw std::length_error("More than maxLength elements in range.");
}
template
static typename std::enable_if< sizeof...(Vcount) < maxLength,
std::initializer_list >::type generate_n(It begin, It end, It current)
{
if (current != end)
return generate_n(begin, end, ++current);
current = begin;
for (auto it = backingList::list.begin();
it != backingList::list.end();
++current, ++it)
*const_cast(&*it) = *current;
return backingList::list;
}
}
template
std::initializer_list range_to_initializer_list(It begin, It end)
{
return __range_to_initializer_list::generate_n(begin, end, begin);
}
int main()
{
std::vector vec = {1,2,3,4,5,6,7,8,9,10};
std::initializer_list list = range_to_initializer_list(vec.begin(), vec.end());
for (int i : list)
std::cout << i << std::endl;
return 0;
}