順序なしコレクション内のタプルの汎用ハッシュ関数
std::unowned_map コンテナーと std::unowned_set コンテナーにより、要素の効率的な検索と挿入が可能になります。ハッシュ値に基づいて。ただし、カスタム ハッシュ関数を定義せずにこれらのコレクションのキーとしてタプルを使用すると、予期しない動作が発生する可能性があります。
これを修正するには、次のような特定のタプル タイプのハッシュ関数を手動で定義する方法があります。
template<> struct std::hash<std::tuple<int, int>> { size_t operator()(std::tuple<int, int> const& tuple) const { ... } };
このアプローチは機能しますが、使用されるタプル型ごとにハッシュ関数を定義するのは面倒な場合があります。これを自動化するには、汎用ハッシュ関数を次のように実装できます。
#include <tuple> namespace std { namespace { // Code derived from Boost template<class T> inline void hash_combine(std::size_t& seed, T const& v) { ... } // Recursive template code from Matthieu M. template<class Tuple, size_t Index = std::tuple_size<Tuple>::value - 1> struct HashValueImpl { ... }; } template<typename... TT> struct hash<std::tuple<TT...>> { size_t operator()(std::tuple<TT...> const& tuple) const { ... } }; }
この関数は、引数依存の名前検索 (ADL) を利用して、コンパイラーがタプルの型に基づいて正しいハッシュ実装を自動的に選択できるようにします。 .
標準準拠のソリューション
std 名前空間での非標準関数の定義は未定義の動作であることに注意してください。標準に準拠したソリューションの場合、カスタム名前空間を作成し、ハッシュ関数の定義に使用できます:
namespace my_hash { // Forward non-tuple types to the std::hash template<typename TT> struct hash { ... }; // Provide the optimized hash for tuples template<typename... TT> struct hash<std::tuple<TT...>> { ... }; }
このソリューションを使用する場合、順序なしコレクションは次のようにカスタム ハッシュ実装を明示的に参照する必要があります:
unordered_set< std::tuple<double, int>, std::hash<std::tuple<double, int>>, std::equal_to<std::tuple<double, int>> > test;
以上が順序なしコレクション内のタプルに汎用ハッシュ関数を実装するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。