Некоторые могли заметить, что std::hash не поддерживает кортежи. Поэтому я добавил перегрузку, которая кажется «лучше», чем решение, которое я видел до сих пор. У кого-нибудь есть идеи по дальнейшему сокращению этого кода? Обратите внимание, что это убийца компилятора! Единственным, кто смог его скомпилировать, был "Clang 3.2"... Компилятор Intel 13.1 не получает специализации и продолжает говорить "Стандарт C++ не поддерживает хэш-блабла". И нам не нужно говорить об оригинальном компиляторе Microsoft, не так ли?
Кстати, мое решение поддерживает рекурсивные кортежи, такие как std::tuple<std::tuple<int,int>,int>
, поэтому я не уверен, относится ли это также к существующим решениям, которые я видел сегодня.
namespace std
{
template<typename... TTypes>
class hash<std::tuple<TTypes...>>
{
private:
typedef std::tuple<TTypes...> Tuple;
template<int N>
size_t operator()(Tuple value) const { return 0; }
template<int N, typename THead, typename... TTail>
size_t operator()(Tuple value) const
{
constexpr int Index = N - sizeof...(TTail) - 1;
return hash<THead>()(std::get<Index>(value)) ^ operator()<N, TTail...>(value);
}
public:
size_t operator()(Tuple value) const
{
return operator()<sizeof...(TTypes), TTypes...>(value);
}
};
}
hash_combine
Boost и использовал для хэширования всевозможные вещи. Это очень прямолинейно. Я думаю, что это просто было забыто в стандарте. - person Kerrek SB   schedule 27.02.2013hash<tuple<TTypes...>>
, поэтому это должна быть (частичная) специализация, также это должна быть специализация, а не специализация. новый шаблон, потому что вы не можете перегружать шаблоны классов. Это недопустимо, потому что не связано с пользовательским типом. - person Jonathan Wakely   schedule 27.02.2013template
только вnamespace std
на пользовательских типах или типах, которые зависят от пользовательских типов. Вышеприведенное не проходит этот тест. - person Yakk - Adam Nevraumont   schedule 14.05.2014