std::map
и std::unordered_map
не являются взаимозаменяемыми. Они принципиально разные.
std :: map реализован с использованием самоуравновешенного бинарного дерева поиска, и для формирования BST вам необходимо определить, как вы хотите сравнивать ключи (они упорядочены). Например, функция сравнения по умолчанию в std::map
равна std::less
или, по существу, operator<
. поэтому тип Event
должен определять operator<
(функция-член или функция не-член). Однако вы можете изменить функцию сравнения на другие, если хотите, указав функцию сравнения в третьем аргументе шаблона.
например.
std::map<Event, std::vector<std::function<void()>>, MyComp<Event>> _observers;
И myComp
могут быть любыми подходящими объектами функции (функтор, свободная функция, лямбда-функция) с действительными сигнатурами.
* например 1016 *
template <typename Event>
struct MyComp{
bool operator()(const Event& lhs, const Event& rhs) const {
...
}
};
С другой стороны, std::unordered_map
реализован с использованием хеш-таблицы. Как и предполагает его название, они неупорядочены, поэтому им не нужны функции сравнения для работы. Но они должны знать, как хэшировать ключ (по умолчанию std::hash
) в значение типа unsigned int (то есть size_t
), и как определить, совпадают ли два ключа (по умолчанию operator==
).
Если Event
- это определенные пользователем типы, std::hash<Event>
не будет работать. В результате, std::unordered_map
не может быть создано. Тем не менее, вы можете применить ту же логику, что и MyComp выше, и создать обобщенный объект хеш-функции Event. например
template <typename Event>
struct MyHash {
std::size_t operator()(const Event& key) const {
...
}
};
И если вы также хотите определить обобщенную функцию равенства (т. Е. Не использовать operator==
типа Event), вы можете сделать то же самое.
template <typename Event>
struct MyEqual {
bool operator() (const Event& lhs, const Event& rhs) const {
...
}
};
Затем определите unordered_map
как
std::unordered_map<Event, std::vector<std::function<void()>>,
MyHash<Event>, MyEqual<Event>> _observers;
И, конечно, тело MyHash
и MyEqual
должно быть достаточно общим, чтобы оно могло работать для всех или большинства типов Event
, которые вы хотите использовать.