3

actionあらゆる種類の STL コンテナーを受け入れるテンプレートメソッドがありますC。ただし、含まれる項目 ( ) は、 または のいずれかC::value_typeでなければなりません。ここまでは順調ですね:ClassAClassB

struct Whatever {
    template<typename C>
    void action(const C& c) {
        static_assert(std::is_same<typename C::value_type, ClassA>::value ||
                      std::is_same<typename C::value_type, ClassB>::value,
                      "Wrong C::value_type");
        // do something with c
    }
};

// Usage:
Whatever w;
w.action(std::vector<ClassA>{1, 2, 3});
w.action(std::unordered_set<ClassB>{1, 2, 3});

注: 囲んでいるクラスはテンプレートではありません。唯一のテンプレートはまさにこのactionメソッドです。

さて、に応じてC::value_type、メソッドの動作を特化したいと思います。ご想像のとおり、ここから私の脳が溶け始めます。


私はSFINAEが進むべき道だと信じていますが、明らかに私はそれを適切に動作させるにはあまりにも錆びていますstructs.自分。ここに私のヘルパーstructsまたはエラーをコピーしても意味がありません。それはほとんど役に立たないがらくたです。

ただし、10 年間、すべての C++ テンプレート (r) の進化 (またはその時点で SFINAE を使用することさえ) と実際に連絡を取り合っていなかったことを認めなければなりません。

C++11 には、すぐに使用できる SFINAE のような簡単なツールがあり、目的を達成できるのではないかと強く思っていますが、ドキュメントのどこから検索を開始すればよいかさえわかりません。検索エンジンも役に立ちませんでした。一度に新しい情報が多すぎて、自分の問題に関連するものと関連しないものを理解できませんでした。

私は完全に途方に暮れているので、赤ちゃんの一歩を踏み出してSOに尋ねます...私の質問は2つあります。

  • C::value_type最新の C++11 テンプレート ツールを使用する実際のタイプに応じて、メソッドの動作を特殊化するにはどうすればよいですか?
  • オプションで、C実際にコンテナかどうかを確認する標準的な方法はありますか?

ご清聴ありがとうございました。

4

2 に答える 2

3

私はなぜあなたがこれをしないのだろうかと思っています:

 template<typename C>
 void action(const C& c) 
 {
        static_assert(std::is_same<typename C::value_type, ClassA>::value ||
                      std::is_same<typename C::value_type, ClassB>::value,
                      "Wrong C::value_type");

      action_worker(c, static_cast<typename C::value_type*>(0));
 }

private:

 template<typename C>
 void action_worker(const C& c, ClassA *) 
 {
     //specialized code when C::value_type is ClassA
 }

 template<typename C>
 void action_worker(const C& c, ClassB *) 
 {
     //specialized code when C::value_type is ClassB
 }

に応じてC::value_type、 の 2 番目の引数はまたは のaction_workerいずれClassA*かになりますClassB*。これにより、コンパイラは、特殊なコードを記述する正しいオーバーロードを選択できるようになります。

is_container質問の 2 番目の部分については、この回答のクラス テンプレートの実装を参照してください。

それが役立つことを願っています。

于 2013-05-08T04:12:39.483 に答える
1

これらの 2 つのタイプのみをサポートしているため、enable_if の使用を検討します。

struct Whatever
{
    template<typename C>
    typename std::enable_if<std::is_same<typename C::value_type, ClassA>::value, void>::type
    action(const C& c)
    {
        std::cout << "ClassA\n";
    }

    template<typename C>
    typename std::enable_if<std::is_same<typename C::value_type, ClassB>::value, void>::type
    action(const C& c)
    {
        std::cout << "ClassB\n";
    }
};
于 2013-05-08T07:37:37.950 に答える