虽然使用元组键创建无序映射和集合应该很简单,但需要元组的自定义哈希函数可能很乏味。但是有没有办法在不使用可变参数模板的情况下避免这种情况?
在 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>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> { static void apply(size_t& seed, Tuple const& tuple) { hash_combine(seed, std::get(tuple)); } }; } template <typename ... tt> struct hash<:tuple>> { size_t operator()(std::tuple<tt...>& tt) const { size_t seed = 0; HashValueImpl<:tuple>>::apply(seed, tt); return seed; } }; }</:tuple></tt...></:tuple></typename></tuple></class></index></tuple></class></t></class>
为确保符合标准,建议定义哈希函数对于自定义命名空间中的元组,防止 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</tt></typename>
这样,无序映射和集合就可以使用元组键,而无需依赖 ADL,并且完全遵守该标准。
以上是在 C 0x 中,元组可以与没有可变参数模板的无序容器一起使用吗?的详细内容。更多信息请关注PHP中文网其他相关文章!