Amadeus Amadeus - 1 year ago 78
C++ Question

Initialization of std::initializer_list

How can I initialize an

compound of unordered elements?

For example, consider the following code:

#include <unordered_map>
#include <string>

using Type = std::unordered_map<std::string, int>;
void foo(std::initializer_list<Type> l) {}

int main()
Type x = {{"xxx", 0}, {"yyy", 1}}; // compile fine
// std::initializer_list<Type> y = {{"xxx", 0}, {"yyy", 1}};
// foo({{"xxx", 0}, {"yyy", 1}});

If I uncomment the first line, I got (g++ 6.1.1) the error:

error: could not convert ‘{{"xxx", 0}, {"yyy", 1}}’ from ‘’ to ‘std::initializer_list, int> >’
std::initializer_list y = {{"xxx", 0}, {"yyy", 1}};

At the end, what I want to do is to be able to call
like the second commented line, which doesn't compile too.

Answer Source

You are missing a set of {}. You need to have

{{{"xxx", 0}}, {{"yyy", 1}}}

The inside {} creates a std::inializer_list<std::pair<std::string, int>> for the map. The next level up creates each map for the std::initializer_list<Type> and the outer most {} is the extent of the std::initializer_list<Type>. We can expand that to

foo({{{"xxx", 0}}, {{"yyy", 1},{"zzz", 2}}});

which is a std::initializer_list<Type> where the first map has one entry and the second map has 2.