Я використовую об’єкт функтора для обчислення хешу enum class
:
struct EnumClassHash
{
template <typename T>
std::size_t operator()(T t) const
{
return static_cast<std::size_t>(t);
}
};
Тепер ви можете використовувати його як третій шаблон-параметр std::unordered_map
:
enum class MyEnum {};
std::unordered_map<MyEnum, int, EnumClassHash> myMap;
Тож вам не потрібно надавати спеціалізацію std::hash
, відрахування аргументу шаблону робить свою роботу. Крім того, ви можете використовувати слово using
та зробити власне, unordered_map
яке використовує, std::hash
або EnumClassHash
залежно від Key
типу:
template <typename Key>
using HashType = typename std::conditional<std::is_enum<Key>::value, EnumClassHash, std::hash<Key>>::type;
template <typename Key, typename T>
using MyUnorderedMap = std::unordered_map<Key, T, HashType<Key>>;
Тепер ви можете використовувати MyUnorderedMap
з enum class
іншим типом:
MyUnorderedMap<int, int> myMap2;
MyUnorderedMap<MyEnum, int> myMap3;
Теоретично, HashType
можна використовувати std::underlying_type
і тоді EnumClassHash
буде не потрібно. Це може бути приблизно так, але я ще не пробував :
template <typename Key>
using HashType = typename std::conditional<std::is_enum<Key>::value, std::hash<std::underlying_type<Key>::type>, std::hash<Key>>::type;
Якщо ви використовуєте std::underlying_type
твори, це може бути дуже гарною пропозицією для стандарту.
std::hash
на переліченні.