J'utilise un objet foncteur pour calculer le hachage de enum class
:
struct EnumClassHash
{
template <typename T>
std::size_t operator()(T t) const
{
return static_cast<std::size_t>(t);
}
};
Maintenant, vous pouvez l'utiliser comme troisième paramètre de modèle de std::unordered_map
:
enum class MyEnum {};
std::unordered_map<MyEnum, int, EnumClassHash> myMap;
Ainsi, vous n'avez pas besoin de fournir une spécialisation de std::hash
la déduction de l'argument du modèle fait le travail. En outre, vous pouvez utiliser le mot using
et faites votre propre unordered_map
qui utilisent std::hash
o EnumClassHash
en fonction de la 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>>;
Vous pouvez maintenant utiliser MyUnorderedMap
con enum class
ou un autre type :
MyUnorderedMap<int, int> myMap2;
MyUnorderedMap<MyEnum, int> myMap3;
Théoriquement, HashType
pourrait utiliser std::underlying_type
et ensuite le EnumClassHash
ne sera pas nécessaire. Cela pourrait être quelque chose comme ça, mais je n'ai pas encore essayé :
template <typename Key>
using HashType = typename std::conditional<std::is_enum<Key>::value, std::hash<std::underlying_type<Key>::type>, std::hash<Key>>::type;
Si vous utilisez std::underlying_type
fonctionne, pourrait être une très bonne proposition pour la norme.