Если я вас правильно понимаю, вы хотите иметь std::unordered_map<MyClass, Value>
такой, что вы также можете запросить с помощью hash_type
, и у вас будет hash_type h == MyClass m
, если std::hash<MyClass>{}(m) == h
. Это правильно?
Это невозможно в C ++ 17. С C ++ 20 будет добавлена функциональность прозрачных хешей . Вы можете прочитать об этом очень кратко здесь . При этом ваша карта должна удовлетворять определенным свойствам
- Ваш тип равенства
Eq
должен предоставлять тип элемента Eq::is_transparent
, т.е. вы должны указать в нем using is_transparent = some_type;
. (Точный тип без последствий.) - Объект типа
Eq
должен обеспечивать перегрузку для сравнения всех возможных комбинаций типов, которые вы хотите использовать. Т.е. обеспечивают перегрузки для (MyClass, MyClass)
и (MyClass, hash_type)
. - Ваш тип ha sh
Hash
должен предоставить тип элемента Hash::transparent_key_equal
, поэтому снова вставьте в него using transparent_key_equal = some_type;
. - Объект типа
Hash
должен вызываться для каждого типа, который вы хотите использовать. Т.е. у вас должна быть перегрузка operator()
для MyClass
и hash_type
.
Для Eq
вы можете использовать std::equal_to<>
(обратите внимание на пустой ромб!), Если вы предоставляете публично доступно operator==
для соответствующих типов. Это НЕ по умолчанию для unordered_map
.
Насколько мне известно, нет никакого аналагона для std::hash
, поэтому вы должны добавить собственный тип для этого и предоставить его на карту.
Pre-C ++ 20 единственное, что вы можете сделать, если хотите сохранить тип ключа, - это записать преобразование из hash_type
в MyClass
.
Но я чувствую фундаментальную проблему в этом, а именно, что вы видите два объекта MyClass
как идентичные, если они имеют одинаковое значение ha sh. Если это непреднамеренно, вы должны это исправить. Если это преднамеренно, убедитесь, что operator==(MyClass, MyClass)
также сравнивает только хэши.
В последующем случае есть простое решение вашей проблемы. Измените вашу карту на std::unordered_map<hash_type, Value>
и ha sh каждый MyClass
, который вы используете для запроса карты. Если вам нужен обратный поиск, чтобы получить MyClass
из га sh, либо напишите функцию преобразования из hash_type
в MyClass
, если это возможно, в противном случае добавьте еще один std::unordered_map<hash_type, MyClass>
, где вы храните каждый объект типа MyClass
вы когда-либо использовали.