Specialization `std :: hash` for class execution conditions

Suppose I have a simple class types boolean, MyTrait. That is, for any type, TI can do MyTrait<T>::valueand get either true or false. I would like to specialize std::hashfor all types Twhere MyTrait<T>::valueis true. Is there any way to do this? Some unsuccessful attempts:

template <class T, typename std::enable_if<
                                MyTrait<T>::value, int
                            >::type = 0>
struct hash<T> {
...
}

Failure because:

error: default template argument in a class template partial specialization

I also tried to put all of the partial specialization properties after the hash, but then an error message appears for Tbeing in an undetectable context.

Is there any way to do this? At least one previous question about SO does not offer: The specialization of std :: hash for derived classes .

, "", , .

+4
1

std (1)

std:: hash T, , - (: ):

namespace std
{
  template<class T>
    struct hash<std::enable_if_t<IsCustomHashable<T>, T>>
    {
       ...
    };
}

, ,

23 : error: template parameters not deducible in partial specialization:

, (1) .

, - - IsCustomHashable, int?

std:: hash - , .

, , - std:: hash , :

#include <functional>
#include <utility>
#include <unordered_set>


// a base class that defers to a free function.
// the free function can be found via ADL and it can be 
// enabled/disabled with enable_if. it up to you.

template<class T>
  struct impl_hash
  {
    using argument_type = T;
    using result_type = std::size_t;
    result_type operator()(const argument_type& arg) const {
      return hash_code(arg);
    }
  };


// a test class
struct my_hashable
{
  bool operator==(const my_hashable&) const {
    return true;
  }
};

// implement the free function in the same namespace as the argument
// type definition
std::size_t hash_code(const my_hashable& mh)
{
  // calculate hash here
  return 0;
}

// now defining a hash specialisation becomes easy
// you could even macroify it
namespace std
{
  template<>
    struct hash<my_hashable>
      : impl_hash<my_hashable>
    {
    };
}

// check it compiles
int main()
{
  std::unordered_set<my_hashable> my_set;
  my_set.emplace();
  return 0;
}
+2

All Articles