0

ファンクターを作業単位として使用するクラスがあります。Run()メソッドでファンクターへの参照を受け入れます。このクラスが任意のファンクターで動作できるようにするには、これらすべてのファンクターは、次のような基本ファンクタークラスから派生する必要があります。

class baseFunctor{

public:
    virtual void operator()()=0;
    virtual baseFunctor Clone()=0;
};

これは機能しますが、明らかに、これらのファンクターを、voidを返し、パラメーターを受け入れない演算子メソッドを持つように制限します。クラスで、任意のタイプのパラメーターを受け取り、何でも返すことができるファンクターを受け入れることができる必要があります。それは明らかに実行可能ですが、私はそれを行う方法を見つけることができないようです。テンプレート、多重継承の使用を検討しましたが、このファンクターを実行する必要のあるクラスは任意の型を受け入れることができなければならないため、基本クラスの型を受け入れるため、実際の型がわからないという事実に悩まされ続けています関手の。

どの道を見るべきかについての提案をいただければ幸いです。

4

7 に答える 7

2

ファンクターを呼び出すクラスは、提供するパラメーターと、戻り値がある場合はそれをどう処理するかをどのように知るのでしょうか。

于 2009-05-05T17:23:06.623 に答える
1

ですから、私がこの権利を読んでいるなら、あなたは「ビジターパターン」を持っています。見上げるのは良いことかもしれません。

誰かがファンクターに引数を与えるためにどのタイプであるかを知る必要があります。多くの場合、ファンクターでは、引数は派生クラスのフィールドに割り当てられ、operator()はそれらのフィールドを操作します。つまり、ファンクターを呼び出してそれについて何も知らないダムメソッドは、より知識のある人によってクロージャー(メソッドと引数がすべて1つのクラスに含まれる)が与えられます。

operator()で複数の引数を取る汎用ファンクタが必要な場合は、テンプレートを使用すると途中まで到達できますが、アリティごとに1つ必要になります。

于 2009-05-05T17:42:43.567 に答える
1

Boostライブラリ(www.boost.org)を使用することに慣れている場合は、Boot.BindとBoost.Functionが特に興味深いと思うかもしれません。私は過去にそれらを使用して、あなたが話していることに沿って非常に何かを達成しました。

Boost.Bindを使用する場合、ファンクターでカリー化を実行して、ファンクターが期待する引数の数とRunメソッドが期待する引数の数(つまり、ゼロ)の違いを考慮することができます。ファンクターを作成するコードは、引数を特定の値にバインドする必要があるため、Run()に渡すことができる引数なしのファンクターを作成する必要があります。

MV

于 2009-05-05T17:22:11.993 に答える
1

私はニールに同意します。メインクラスは、渡すパラメーターと、これらのファンクターから期待される戻り値を知っている必要があります。「ファンクター」を、必要な引数と戻り値を持つ関数をサポートする適切なクラスに型キャストできますか?

class baseFunctor
{
};

class functor1x2: public baseFunctor
{
public:
    virtual void* execute(void*, void*);

}

class MainClass
{
public:
   void Execute(baseFunctor* ipFunctor)
   {
      functor1x2* lpFunctor1x2 = dynamic_cast<functor1x2*>(ipFunctor);
      if(lpFunctor1x2)
      {
         lpFunctor1x2->execute(NULL, NULL);
      }
   }
}

Drewが指摘したように、Visitorパターンでは簡単に達成できなかった、このアプローチで何が達成できるかはわかりません。

于 2009-05-05T18:05:14.603 に答える
0

なぜファンクターを返却したいのですか?状態も保存していますか?正確に何をしたいのかが明確ではないので、もう少し詳しく説明していただければ幸いです。

継承を使用する場合は、共変リターン型(および仮想コンストラクターのイディオム)を調べてください。

さて、問題の本質についてです。問題は、実際にはファンクターを渡すことではなく、ファンクターのアプリケーションにあります。boost::lambdaboost::parameter同様に見てみたいと思うかもしれません。

于 2009-05-05T17:20:05.930 に答える
0

C ++のvarargsのように、省略記号の引数が必要だと思います。

于 2009-05-05T17:21:38.110 に答える
0

おそらくstd::tr1 :: functionはあなたにとって興味深いですか?

于 2009-05-05T17:27:17.613 に答える