ホームページ > バックエンド開発 > C++ > C 0x で可変個引数テンプレートを使用せずに、タプルは順序付けされていないコンテナーで動作できますか?

C 0x で可変個引数テンプレートを使用せずに、タプルは順序付けされていないコンテナーで動作できますか?

Susan Sarandon
リリース: 2024-11-12 01:16:03
オリジナル
970 人が閲覧しました

Can Tuples Work with Unordered Containers Without Variadic Templates in C  0x?

C 0x タプルを順序なしコンテナで動作させる

タプル キーを使用して順序なしマップとセットを作成するのは簡単ですが、タプルにカスタム ハッシュ関数を要求するのは面倒な場合があります。しかし、可変引数テンプレートを使用せずにこれを回避する方法はありますか?

標準的な解決策

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&amp; seed, T const&amp; 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&amp; seed, Tuple const&amp; 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&amp; seed, Tuple const&amp; tuple)
          {
            hash_combine(seed, std::get<0>(tuple));
          }
        };
    }

    template <typename ... TT>
    struct hash<std::tuple<TT...>> 
    {
        size_t
        operator()(std::tuple<TT...>&amp; 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&amp; tt) const
    {                                              
        return std::hash<TT>()(tt);                                 
    }                                              
};
}

// ... Include the rest of the previous generic hash function code
ログイン後にコピー

このようにして、順序なしマップとセットは、ADL に依存せずにタプル キーで動作できます。そして基準は完全に遵守されています。

以上がC 0x で可変個引数テンプレートを使用せずに、タプルは順序付けされていないコンテナーで動作できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート