【发布时间】:2015-04-06 17:19:24
【问题描述】:
我希望能够使用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> 返回相同的种子?
【问题讨论】:
-
您可以使用
^来组合哈希。另请参阅stackoverflow.com/questions/5889238/… 编辑:第二个想法:这可能对std::pair<A, A>不利,因为所有具有相等值的对都将具有哈希0。 -
@Wintermute 感谢您的回复,我已经看到了该线程,但是正如您已经提到的,由于您还提到了恶化,这不适合我的需求;)。跨度>
-
to return the same seed for std::pair<A, B> and std::pair<B, A>为什么,如果你不介意我问?你想解决什么问题,这个(相当不寻常的)属性有什么帮助? -
@Wintermute 这可以通过只采用单个模板参数的特化来解决,这与采用两个模板参数的特化不同。也许
static_assert以确保双参数模板的用户不会为两个模板参数提供相同的类型。不完美,但总比没有好。 -
为什么不只是
hash(first) + hash(second)?
标签: c++ c++11 hash stl std-pair