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
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;
}
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
.