4

注: 次の質問は、テンプレート メソッド デザイン パターンC++ 関数テンプレートに関するものです。両方を区別するために、デザイン パターンを参照するときは斜体を使用し、C++ テンプレートを参照するときは太字を使用します。

テンプレート メソッド パターンのアイデアは、アルゴリズムの一部を交換可能にすることです。これは通常、サブクラスが基本クラスのアルゴリズムにプラグインされる具体的な実装を提供する継承によって実現されます。ただし、フック メソッドをtemplatesにする必要がある場合、テンプレートを仮想にすることはできないため、これは機能しません。コンパイルされない簡単な例を次に示します。

class Base
{
public:

    // This is the template method
    template <typename T>
    void doSomething(T input)
    {
        //...
        auto converted = ConvertInput(input);
        //...
        std::cout << converted;
    }

protected:
    //compile error "member function templates cannot be virtual"
    template <typename T>
    virtual T ConvertInput(T input) = 0;
};

class Derived : public Base
{
protected:
    template <typename T>
    T ConvertInput(T input)
    {
        return 2 * input;
    }
};

int main()
{
    Derived d;
    d.doSomething(3);
}

関数テンプレートフックを使用するテンプレート メソッドを実装する方法はありますか?

Baseクラスをどこでも型として使用することに興味はありません。コンパイル時の最適化を最大限に実現するために、常に具象固有の型を使用します。したがって、この質問の別の定式化は次のとおりです。実装全体で共通のコード スケルトンを共有する関数テンプレートDerived-1 .. Derived-nを持つ複数のクラスを作成するにはどうすればよいでしょうか?

4

2 に答える 2

3

CRTP は Base をテンプレートにすることで問題を解決します。

T有限集合に由来する場合、または変換が任意でない場合、型消去は機能します。

有限セットの場合は、派生したすべての仮想メソッドを消去します。共通のプロパティの場合は、そのプロパティを消去し、それに作用するメソッドを仮想化します。または混合物。

operator()それ以外の場合、 Base は、 virtual を使用して検索するのではなく、操作を関数オブジェクトとして受け取るテンプレート メソッドを ( templateを使用して) 持つことができます。Derived は、テンプレート化された操作を引数として Base メソッドに渡します。これは基本的に CRTP なしの CRTP です。

于 2016-10-16T21:02:46.903 に答える