Я наткнулся на этот очень старый вопрос, пытаясь найти тот же ответ, и найти существующие ответы не очень полезными. В настоящее время мы используем unordered_map
, если нам нужна хеш-карта, и лучший способ сделать ваш класс MyKeyObject
пригодным для использования в качестве ключа в hash_map в целом - это определить хеш-функцию для класса и указать стандартной библиотеке использовать эта хеш-функция для карт. Это означает, что мы можем создать экземпляр шаблона карты, не всегда предоставляя хеш-функцию.
Страница википедии *1006* на «Неупорядоченные ассоциативные контейнеры в C ++» предоставляет простой для подражания пример, я немного ошарашил его и применил к вашему случаю. Сначала мы определим простую хеш-функцию как метод-член:
#include <functional>
class MyKeyObject {
private:
std::string str1;
std::string str2;
public:
inline size_t hash() const {
return std::hash<std::string>()(str1) ^ std::hash<std::string>()(str2);
}
inline bool operator==(const MyKeyObject& other) const {
return str1 == other.str1 && str2 == other.str2;
}
};
Для того, чтобы сделать хеш-функцию, мы вместе переписываем хэши всех содержащихся объектов. Это делается с помощью std::hash
, шаблона, который должен быть создан с дочерним типом. Обратите внимание, что мы не можем использовать это как третий параметр шаблона для unordered_map. Обратите также внимание на оператор const-equals.
Теперь мы должны сообщить стандартной библиотеке, что это хеш-функция, которая будет использоваться для MyKeyObject
значений:
namespace std {
template <>
class hash<MyKeyObject> {
public:
size_t operator()(const MyKeyObject &aMyKeyObject) const {
return aMyKeyObject.hash();
}
};
}
Это добавляет специализацию шаблона к шаблонному классу std::hash
, предоставляя оператор хеширования для класса MyKeyObject
. В примере нет на странице википедии здесь прямо определяется хеш, вместо вызова хеш-функции, которая является членом объекта - но если хеш-функция должна обращаться к закрытым членам, это не сработает.
Теперь вы можете использовать MyKeyObject
в unordered_map
, например так:
std::unordered_map<MyKeyObject, MyData> _myDataHashMap;
(проверено clang / xcode)