Я поделюсь этим здесь, так как это может быть полезно для других, ищущих это решение: начиная с @ KarlvonMoor ответа, вот вариант шаблона с вариадным кодом, который является более кратким в его использовании, если вам нужно объединить несколько значений вместе:
inline void hash_combine(std::size_t& seed) { }
template <typename T, typename... Rest>
inline void hash_combine(std::size_t& seed, const T& v, Rest... rest) {
std::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
hash_combine(seed, rest...);
}
Использование:
std::size_t h=0;
hash_combine(h, obj1, obj2, obj3);
Первоначально он был написан для реализации макроса variadic, чтобы легко сделать настраиваемые типы хэшируемыми (что я считаю одним из основных применений функции hash_combine
):
#define MAKE_HASHABLE(type, ...) \
namespace std {\
template<> struct hash<type> {\
std::size_t operator()(const type &t) const {\
std::size_t ret = 0;\
hash_combine(ret, __VA_ARGS__);\
return ret;\
}\
};\
}
Использование:
struct SomeHashKey {
std::string key1;
std::string key2;
bool key3;
};
MAKE_HASHABLE(SomeHashKey, t.key1, t.key2, t.key3)
// now you can use SomeHashKey as key of an std::unordered_map