Search code examples
c++constructorinitializer-list

How to implement initializer_list constructor for a wrapper of std::map


Here is a simple wrapper class for std::map. I want to be able to use an initializer list to construct objects of type Wrapper (see main function), however this implementation does not work.

#include <map>
#include <initializer_list>

struct Key {
    Key(int k) : key(k) {}
    int key;
};

struct Value{
    Value(int v) : value(v) {}
    int value;
};

class Wrapper {
    public:
        Wrapper(std::initializer_list<std::pair<Key, Value>> initList) 
            : m_map(initList) {}

    private:
        std::map<Key, Value> m_map;
};


int main() {
    Wrapper w = {{2, 2}, {1,1}};
}

The compiler gives me this error:

error: no matching constructor for initialization of 'std::map<Key, Value>' : m_map(initList) {}

It was my understanding that the template parameter for std::intializer_list is supposed to be what the container that is being initialized is storing internaly. Since std::map stores key-value pairs as std::pair<const key_type, value_type> I thought this was correct I also tried explicitly adding const in both m_map definition and in the constructor (like std::initializer_list<std::pair<const Key, Value>> but I am still getting compile errors


Solution

  • Note that Key should be const in the initializer_list:

    Wrapper(std::initializer_list<std::pair<const Key, Value>> initList) 
    

    A std::map also needs the Key s to be comparable using operator<. You can add it as a free function:

    bool operator<(const Key& lhs, const Key& rhs) {
        return lhs.key < rhs.key;
    }
    

    Demo

    or as a member function

    struct Key {
        Key(int k) : key(k) {}
    
        bool operator<(const Key& rhs) const {
    //                                 ^^^^^   <- note that it should be const
            return key < rhs.key;
        }
    
        int key;
    };
    

    Demo - The member function needs to be const because the map couldn't call a non-const qualified member function on a Key since the Key s are not allowed to change once inserted into the map.