c++ - 如何 std::hash 一个无序的 std::pair

标签 c++ c++11 hash stl 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 中元素的顺序(即,为 std::pair<A, B>std::pair<B, A>) 返回相同的种子。

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

问:

是否有一种标准的方法来散列 std::pair ,这样元素的顺序将被忽略,并且为 std::pair<A, B> 返回相同的种子和 std::pair<B, A>

最佳答案

不要排序对,排序散列:

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]

关于c++ - 如何 std::hash 一个无序的 std::pair,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28367913/

相关文章:

c++ - 如何使用 C++11 线程功能同步 2 个函数?

C++11 垃圾收集器 - 为什么和如何

c++ - 如何在 C++ 中获取文件的 MD5 哈希?

c++ - 使用 C++ 编译 GNU C 项目

c++ - 使用 iOS 或 c/c++ 访问 SVN 或远程 Git 存储库等

C++:如何在不向 shell 传递命令的情况下执行文件?

C++:使用 auto 还是 typedef?

c++ - 如何检查 cpp 中给定输入的数据类型?

php - 在 PHP 中使用资源作为数组索引

mysql - 通过 MySQL (phpmyadmin) 恢复密码?