How to enable copied initializer lists for my own collection class?

Given this example, the class:

template<typename T> class ExampleContainer { private: std::map<T, int> _objects; int _sum; public: ExampleContainer() : _objects(), _sum(0) { } void Add(T obj, int add) { _objects[obj] = add; // yes this is bad, but it an example. _sum += add; } }; 

What you need to be able to use it as follows:

 ExampleContainer<char*> _rarities = { { "One", 600 }, { "Two", 200 }, { "Three", 50 }, { "Four", 10 }, { "Five", 1 }, }; 

I know that this should be somehow possible, because I can initialize std :: map as it already is.

Thanks in advance for any answers.

+4
source share
1 answer

Just add a constructor that takes std::initializer_list to your ExampleContainer class:

 ExampleContainer(std::initializer_list<typename std::map<T, int>::value_type> l) : _objects(l) { } 

This will be called every time you use curly braces to initialize the object, as in this case:

 ExampleContainer<char*> _rarities = { ... }; 

Thus, each record in braces will become an element of the initializer list.

Since the basic type of the initializer list is std::map<T, int>::value_type , temporary objects of this type will be built from the values ​​you provide:

 ExampleContainer<char*> _rarities = { { "One", 600 }, // Each of these entires will cause the creation of { "Two", 200 }, // a temporary object of type: { "Three", 50 }, // std::pair<char* const, int> { "Four", 10 }, // that will become an element of the initializer { "Five", 1 }, // list received by the constructor. }; 

Also note that the conversion from a string literal to char* is deprecated in C ++ 03 and not valid in C ++ 11 (string literals are of type char const[] in C ++ 11). Thus, you may want to specify the type ExampleContainer<char const*> instead of the _rarities variable (the array type C decomposes into pointer types).

UPDATE:

As @LightnessRacesInOrbit correctly pointed out in the comments, this approach is dangerous if you are not going to use only string literals in your container (this is what I assume from your example, but doesn’t really mean anything), It is better to use std::string instead std::string (so you should declare _rarities as ExampleContainer<std::string> ).

+11
source

All Articles