Я использую объект функтора для вычисления хэша 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
работает, это может быть очень хорошим предложением для стандарта.
person
Daniel
schedule
20.07.2014
std::hash
для типа перечисления. - person Kerrek SB   schedule 17.09.2013