From 25168fc73da1ab022ac5654fd4d3090107f4d932 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 1 Mar 2015 13:32:34 +0200 Subject: [PATCH] enum: fix std::hash<> non-specialization for enum types SFINAE only works for substituted template parameters, not any complication error (or it would be called CEINAE); therefore hash for enums will fail to compile, given a non-enum, rather than being ignored. It's not possible to specialize hash<> for enums, since the primary template does not have en extra Enable template argument for use with enable_if. We therefore rename it to enum_hash<> and require users to explicitly define hash as inheriting from it. --- core/enum.hh | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/core/enum.hh b/core/enum.hh index c98d83a3f2..be6c4ff984 100644 --- a/core/enum.hh +++ b/core/enum.hh @@ -22,24 +22,21 @@ #pragma once /* - * This header file defines a hash function for all enum types, using the + * This header file defines a hash function for enum types, using the * standard hash function of the underlying type (such as int). This makes - * it possible to use an enum type as a key for std::unordered_map, for - * example. + * it possible to inherit from this type to */ #include #include #include -namespace std { - template - class hash { - using sfinae = typename std::enable_if::value, T>::type; - public: - std::size_t operator()(const T& e) const { - using utype = typename std::underlying_type::type; - return std::hash()(static_cast(e)); - } - }; -} +template +class enum_hash { + static_assert(std::is_enum::value, "must be an enum"); +public: + std::size_t operator()(const T& e) const { + using utype = typename std::underlying_type::type; + return std::hash()(static_cast(e)); + } +};