如何 std::hash 一个无序的 std::pair

How to std::hash an unordered std::pair

我希望能够使用 std::pair 作为 unordered_container 中的键。我知道我可以通过以下方式做到这一点:

template<typename T>
void
hash_combine(std::size_t &seed, T const &key) {
  std::hash<T> hasher;
  seed ^= hasher(key) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}

namespace std {
  template<typename T1, typename T2>
  struct hash<std::pair<T1, T2>> {
    std::size_t operator()(std::pair<T1, T2> const &p) const {
      std::size_t seed(0);
      ::hash_combine(seed, p.first);
      ::hash_combine(seed, p.second);
      return seed;
    }
  };
}

但是,我希望散列忽略 std::pair 中元素的顺序(即 return std::pair<A, B>std::pair<B, A>) 的相同种子。

我认为实现此目的的一种方法是在创建我的 std::pair<A, B> 时应用某种排序(即某种自定义 std::make_pair)。 但这过于严格,因为对象 A, B 可能没有顺序。

问:

是否有一种标准方法来对 std::pair 进行哈希处理,以便忽略元素的顺序,并为 std::pair<A, B> 和 [=22= 编辑相同的种子 return ]?

不要排序对,排序散列:

namespace std {
  template<typename T1, typename T2>
  struct hash<std::pair<T1, T2>> {
    std::size_t operator()(std::pair<T1, T2> const &p) const {
      std::size_t seed1(0);
      ::hash_combine(seed1, p.first);
      ::hash_combine(seed1, p.second);

      std::size_t seed2(0);
      ::hash_combine(seed2, p.second);
      ::hash_combine(seed2, p.first);

      return std::min(seed1, seed2);
    }
  };
}

[Live example]