While creating unordered maps and sets using tuple keys should be straightforward, requiring a custom hash function for tuples can be tedious. But is there a way to avoid this without using variadic templates?
In C 0x, a generic hash function for tuples can be defined using the code below:
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; } }; }
To ensure compliance with the standard, it's recommended to define the hash function for tuples in a custom namespace, preventing it from being automatically picked up by ADL. This requires declaring the hash implementation in the custom namespace first, followed by including the rest of the generic hash function code:
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
This way, unordered maps and sets can work with tuple keys without relying on ADL, and the standard is fully adhered to.
The above is the detailed content of Can Tuples Work with Unordered Containers Without Variadic Templates in C 0x?. For more information, please follow other related articles on the PHP Chinese website!