Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++0x nested initializer lists

I would like to use C++0x new initializer list feature to initialize a std::vector with a compile time defined number of items for a new API I'm currently working on. Something like this:

template<int n>
std::initializer_list<std::string> duplicate(std::string s) {
  // return s duplicated n times
  return { s, s, s };
}

std::vector<std::string> v = { "foo",  duplicate<3>("bar") };

Do you have any idea how to accomplish this? Is it even possible? I'm aware of that I will need to use TMP and recursion to build up the list of duplicated strings and finally access it somehow through a constant (e.g., enum). But it seems that I cannot even nest the initializer list like this.

like image 576
roy Avatar asked Apr 30 '11 09:04

roy


1 Answers

You cannot nest initializer lists in order to extend them, nor can you add/concatenate them. They are only a bit of syntactic sugar to access a compile-time-sized array. Even copying initializer_lists doesn't copy their items. Most importantly, this means you cannot use the return value of duplicate! The referenced array is destroyed when the function returns, per 8.5.4p6 in N3290:

The lifetime of the array is the same as that of the initializer_list object.

(A temporary is created in the return statement and then returned by value. Even if copy elision happens, all other semantics of copying are unchanged.)

Compare to, for example, the temporary initializer_list created here, which is then passed to the ctor and destroyed after the object is initialized, at the same point all other temporary objects in the same full expression (if there were any) would be destroyed:

vector<string> v {"foo"};

Instead of manipulating initializer lists, use vector's method to insert N copies:

v.insert(v.end(), 3, "bar");
like image 170
Thomas Edleson Avatar answered Sep 19 '22 02:09

Thomas Edleson