12

たとえば、いくつかの関数テンプレートがあります

template <typename T>
void foo(T);

template <typename T>
void bar(T);

// others

そして、私はそれぞれをさまざまなタイプで呼び出すアルゴリズムに渡す必要があります。

template <typename F>
void some_algorithm(F f)
{
    // call f with argument of type int
    // call f with argument of type SomeClass
    // etc.
}

some_algorithm関数テンプレートをインスタンス化せずに渡すことはできませんが、いくつかの異なる型の引数を使用して呼び出す必要があるため、特定の型でインスタンス化することもできません。

関数テンプレートを多形関数オブジェクトに適合させることができます。

struct foo_polymorphic
{
    template <typename T>
    void operator()(T t)
    {
        foo(t);
    }
};

次に、それをとして渡しますsome_algorithm(foo_polymorphic())。ただし、これには、関数テンプレートごとに個別のアダプターを作成する必要があります。

関数テンプレートをポリモーフィック関数オブジェクトに適応させる一般的な方法はありますか?つまり、それぞれに個別に何かを宣言することなく、適応する必要のある関数テンプレートごとに再利用できるメカニズムはありますか?

4

2 に答える 2

2

問題の短いバージョンには、オーバーロードされた名前が付けられ、最終的に を呼び出すようなfオブジェクトを簡潔に記述する方法が示されています。ffff(a0, a1, a2, ...)f(a0, a1, a2, ...)

あなたが指摘するように、ポリモーフィックファンクターは通常の解決策です。しかし、それは(テンプレートメンバーがあるため)外で定義する必要があるため、回答の目的には十分に簡潔ではないと考えます。

現在、ラムダ式は単相ファンクターを生成するため、近いですが完全ではありません。

// set of functions overloaded on int and double
void f(int);
void f(double);

auto ff = [](int i) { return f(i); };

GMan がコメントで指摘したように、ポリモーフィック ラムダは、ポリモーフィック ファンクターをインラインで簡潔に記述するためのソリューションです (すべきでしょうか?)。

make_overloadそれまでの間、複数のファンクターを 1 つに結合するヘルパーを作成することができます。

auto ff = make_overload(
    [](int arg0) { return f(arg0); }
    , [](double arg0) { return f(arg0); } );

オーバーロード セット全体を「キャプチャ」します。おそらく、Boost.Preprocessor マクロがここで役立つ可能性があるため、auto ff = POLYMORPHIC_LAMBDA( 1, (int)(double), { return f(arg0); } );インラインで使用できます。ただし、通常の行外の手書きのポリモーフィック ファンクター ソリューションとは異なり、アリティ制限があると思われます (したがって、最初のマクロ引数)。したがって、これは可変関数テンプレートなどでは役に立ちません。

于 2011-08-11T23:12:59.633 に答える
1

テンプレート テンプレート パラメーターを使用できなかったのはなぜですか? テンプレートをインスタンス化せずに渡すことはできないとおっしゃいましたが、これについて以前に聞いたことがあるかどうかはわかりません。

あなたのコード構造がどのように見えるかわかりませんが、次のようなことができますか

私はこれが機能することを知っていますが、それがあなたが望むものかどうかはわかりません:

template<typename T>
T some_algorithm(T data) { return T(); } // just returning nothing for example

template<typename T, T(*Something)(T)>
class FuncClass {
public:
    T run(T data) { return Something(data); }
};

template<typename T, typename Functor>
void apply_algorithm(T data) {
    Functor F;
    F.run(data);
}

int main() {
    int mydata = 4;
    apply_algorithm<int, FuncClass<int, some_algorithm<int> > >(mydata);

    cin.get();
}
于 2011-08-11T22:41:25.650 に答える