unowned_map/unowned_set のタプルの汎用ハッシュ
Q: なぜ std::unowned_map
標準 C では、unowned_map や unowned_set などの連想コンテナーでタプルをキーとして使用するには、カスタム ハッシュ関数を定義する必要があります。
Q: 可変個引数テンプレートを使用せずに 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; } }; }<p><strong>Q: より簡単な解決策はありますか? ?</strong></p> <p><strong>標準非準拠ソリューション (ADL 有効):</strong></p> <pre class="brush:php;toolbar:false">#include <tuple> 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 なし):
厳密な標準準拠を達成するには、上記のコードを別の名前空間 (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::unowned_map」を機能させるにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。