Вы не можете реализовать qHash
с помощью boost::hash_range
/ boost::hash_combine
(что фактически делает ответ pmr), потому что QSet
является эквивалентом Qt std::unordered_set
, и, так как Название STL предполагает, что эти контейнеры неупорядочены , тогда как Boost Documentation утверждает, что hash_combine
зависит от порядка, то есть. он будет хешировать перестановки в различных хеш-значениях.
Это проблема, потому что если вы наивно хешируете элементы в сохраненном порядке
Вы не можете гарантировать, что два набора, которые сравнивают равные, действительно равны, что является одним из требований хеш-функции:
For all x, y: x == y => qHash(x) == qHash(y)
Таким образом, если вашей функции объединения хэшей необходимо произвести одинаковые выходные данные для любой перестановки входных значений, она должна быть коммутативной . К счастью, как (без знака) добавление, так и операция xor просто отвечают всем требованиям:
template <typename T>
inline uint qHash(const QSet<T> &set, uint seed=0) {
return std::accumulate(set.begin(), set.end(), seed,
[](uint seed, const T&value) {
return seed + qHash(value); // or ^
});
}