雖然使用元組鍵創建無序映射和集合應該很簡單,但需要元組的自定義哈希函數可能很乏味。但是有沒有辦法在不使用可變參數模板的情況下避免這種情況?
在C 0x 中,可以使用以下程式碼定義元組的通用雜湊函數:
namespace std{ namespace { // Code from boost // Reciprocal of the golden ratio helps spread entropy // and handles duplicates. // See Mike Seymour in magic-numbers-in-boosthash-combine: // http://stackoverflow.com/questions/4948780 template <class T> inline void hash_combine(std::size_t& seed, T const& v) { seed ^= std::hash<T>()(v) + 0x9e3779b9 + (seed<<6) + (seed>>2); } // Recursive template code derived from Matthieu M. 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...>& tt) const { size_t seed = 0; HashValueImpl<std::tuple<TT...>>::apply(seed, tt); return seed; } }; }
為了確保符合標準,建議在自訂命名空間中為元組定義雜湊函數,以防止它被ADL 自動選取。這需要先在自訂命名空間中聲明雜湊實現,然後包含其餘通用雜湊函數程式碼:
namespace hash_tuple{ template <typename TT> struct hash { size_t operator()(TT const& tt) const { return std::hash<TT>()(tt); } }; } // ... Include the rest of the previous generic hash function code
這樣,無序映射和集合就可以使用元組鍵,而無需依賴ADL ,並且完全遵守該標準。
以上是在 C 0x 中,元組可以與沒有可變參數模板的無序容器一起使用嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!