C++11 Hash function for any enum type

Draco Ater picture Draco Ater · Mar 10, 2012 · Viewed 7.3k times · Source

I am writing a hash function for my object. I already can hash containers, and combine hashes, thanks to Generic Hash function for all STL-containers. But my classes also have enums. Of course I can create a hash function for every enum, but it does not seem like a good idea. Is it possible to create some generic specification for std::hash, so that it could be applied to every enum? Something like that, using std::enable_if and std::is_enum

namespace std {
  template <class E>
  class hash<typename std::enable_if<std::is_enum<E>::value, E>::type> {
  public:
    size_t operator()( const E& e ) const {
      return std::hash<std::underlying_type<E>::type>()( e );
    }
  };
};

PS. This code does not compile

error: template parameters not used in partial specialization:
error:         ‘E’

Answer

Johannes Schaub - litb picture Johannes Schaub - litb · Mar 10, 2012

Your E parameter cannot be deduced, because the compiler cannot know that your enable_if<...>::type ends up denoting E again (and in fact, there are some specializations of it that by design don't do that!). It's called a "non-deduced context" for E.

If hash has only one parameter, there is no way (that I am aware of) to SFINAE out your partial specialization.