Everyone creates std::vector
from std::initializer_list
, but what about the other way around?
eg. if you use a std::initializer_list
The answer is NO, you cannot do that.
An object of type std::initializer_list
is a lightweight proxy object that provides access to an array of objects of type T. A std::initializer_list
object is automatically constructed when:
As far as library support goes, std::initializer_list
only has a default constructor that constructs an empty list, and its iterators are constant. The lack of a push_back()
member means you cannot apply e.g. a std::copy
with a std::back_inserter
iterator adaptor to fill it, and neither can you assign through such iterators directly:
#include
#include
#include
#include
int main()
{
auto v = std::vector { 1, 2 };
std::initializer_list i;
auto it = std::begin(i);
*it = begin(v); // error: read-only variable is not assignable
}
Live Example
If you look at the Standard Containers, in addition to accepting std::initializer_list
in their constructors / inserters, they all have constructors / inserters taking an iterator pair, and the implementation is likely to delegate the initializer_list
function to the corresponding iterator pair function. E.g. the std::vector
iterator insert(const_iterator __position, initializer_list __il)
{return insert(__position, __il.begin(), __il.end());}
You should modify your code along similar lines:
void someThing(std::initializer_list items)
{
someThing(items.begin(), items.end()); // delegate
}
template
void someThing(It first, It last)
{
for (auto it = first, it != last; ++it) // do your thing
}
In times when you have your items in a vector instead of a literal list:
std::vector v = { 1, 2 };
auto i = { 1, 2 };
someThing(begin(v), end(v)); // OK
someThing(i); // also OK
someThing({1, 2}); // even better