The answer is NO, you cannot do that.
An object of type std::initializer_list<T>
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:
- a braced-init-list is used in list-initialization, including function-call list initialization and assignment expressions (not to be confused with constructor initializer lists)
- a braced-init-list is bound to auto, including in a ranged for loop
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 <algorithm>
#include <initializer_list>
#include <iterator>
#include <vector>
int main()
{
auto v = std::vector<int> { 1, 2 };
std::initializer_list<int> i;
auto it = std::begin(i);
*it = begin(v); // error: read-only variable is not assignable
}
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<T>::insert
function in libc++ is this simple one-liner:
iterator insert(const_iterator __position, initializer_list<value_type> __il)
{return insert(__position, __il.begin(), __il.end());}
You should modify your code along similar lines:
void someThing(std::initializer_list<int> items)
{
someThing(items.begin(), items.end()); // delegate
}
template<class It>
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<int> v = { 1, 2 };
auto i = { 1, 2 };
someThing(begin(v), end(v)); // OK
someThing(i); // also OK
someThing({1, 2}); // even better