如何 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);
}
};
}
我希望能够使用 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);
}
};
}