unordered_map/unordered_set 中元組的通用雜湊
問:為什麼std::unordered_map
在標準 C 中,要使用元組作為關聯容器(如 unordered_map 或 unordered_set)中的鍵,您需要定義自訂雜湊函數。
問:可以在不使用可變參數模板的情況下對 C 0x 元組進行自動化嗎?
可以,使用以下程式碼:
namespace std{ namespace { template <class T> inline void hash_combine(std::size_t& seed, T const& v) { seed ^= std::hash<T>()(v) + 0x9e3779b9 + (seed<<6) + (seed>>2); } template <class Tuple, size_t Index = std::tuple_size<Tuple>::value - 1> struct HashValueImpl { static void apply(size_t& seed, Tuple const& tuple) { HashValueImpl<Tuple, Index-1>::apply(seed, tuple); hash_combine(seed, std::get<Index>(tuple)); } }; template <class Tuple> struct HashValueImpl<Tuple,0> { static void apply(size_t& seed, Tuple const& tuple) { hash_combine(seed, std::get<0>(tuple)); } }; } template <typename ... TT> struct hash<std::tuple<TT...>> { size_t operator()(std::tuple<TT...> const& tt) const { size_t seed = 0; HashValueImpl<std::tuple<TT...> >::apply(seed, tt); return seed; } }; }
問:是否有更簡單的解?
標準不合格解決方案(啟用ADL):
#includenamespace std{ namespace { template <class T> inline void hash_combine(std::size_t& seed, T const& v) { seed ^= std::hash<T>()(v) + 0x9e3779b9 + (seed<<6) + (seed>>2); } template <class Tuple, size_t Index = std::tuple_size<Tuple>::value - 1> struct HashValueImpl { static void apply(size_t& seed, Tuple const& tuple) { HashValueImpl<Tuple, Index-1>::apply(seed, tuple); hash_combine(seed, std::get<Index>(tuple)); } }; template <class Tuple> struct HashValueImpl<Tuple,0> { static void apply(size_t& seed, Tuple const& tuple) { hash_combine(seed, std::get<0>(tuple)); } }; } template <typename ... TT> struct hash<std::tuple<TT...>> { size_t operator()(std::tuple<TT...> const& tt) const { size_t seed = 0; HashValueImpl<std::tuple<TT...> >::apply(seed, tt); return seed; } }; }
標準合格解決方案(無ADL):
為了達到嚴格的標準一致性,您必須將上述程式碼移至單獨的命名空間(例如hash_tuple)中,並修改語法以明確指定自訂雜湊函數。
namespace hash_tuple{ // Forward non-tuple types to std::hash template <typename TT> struct hash { size_t operator()(TT const& tt) const { return std::hash<TT>()(tt); } }; }
取代 hash_combine 和來自不合格解決方案的 HashValueImpl 及其 hash_tuple 對應項。最後,使用以下語法:
unordered_set<tuple<double, int>, hash_tuple::hash<tuple<double, int>>> test2;
以上是如何在不定義自訂雜湊函數的情況下使“std::unordered_map”工作?的詳細內容。更多資訊請關注PHP中文網其他相關文章!