I use a functor object to calculate hash of enum class
:
struct EnumClassHash
{
template <typename T>
std::size_t operator()(T t) const
{
return static_cast<std::size_t>(t);
}
};
Now you can use it as 3rd template-parameter of std::unordered_map
:
enum class MyEnum {};
std::unordered_map<MyEnum, int, EnumClassHash> myMap;
So you don't need to provide a specialization of std::hash
, the template argument deduction does the job. Furthermore, you can use the word using
and make your own unordered_map
that use std::hash
or EnumClassHash
depending on the Key
type:
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>>;
Now you can use MyUnorderedMap
with enum class
or another type:
MyUnorderedMap<int, int> myMap2;
MyUnorderedMap<MyEnum, int> myMap3;
Theoretically, HashType
could use std::underlying_type
and then the EnumClassHash
will not be necessary. That could be something like this, but I haven't tried yet:
template <typename Key>
using HashType = typename std::conditional<std::is_enum<Key>::value, std::hash<std::underlying_type<Key>::type>, std::hash<Key>>::type;
If using std::underlying_type
works, could be a very good proposal for the standard.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…