2009-05-05 17 views
0

私は、ファンクションを作業単位として使用するクラスを持っています。 Run()メソッドでファンクタへの参照を受け入れます。このクラスは、任意のファンクタを操作できるようにするには、これらすべてのファンクタは次のようになり、私の基本数子クラスから派生しなければなりません:これは動作します任意の戻り値の型と任意のパラメータを持つ派生Functor

class baseFunctor{ 

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

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

どのような道を見るかについてのご意見をいただければ幸いです。

答えて

2

あればどのよう数子を呼び出すクラスは、どのようなパラメータを提供するために、どのような戻り値で行うために知っているのだろうか?

0

なぜあなたはファンクタを返そうとしていますか?あなたもいくつかの状態を保存していますか?正確に何をしたいのかははっきりしていないので、もう少し詳しくお聞かせください。

継承を使用する場合は、共変の戻り値の型(およびVirtual Constructor idiom)を参照してください。

問題の肉にとって、問題は実際にはファンクタを渡すのではなく、ファンクタのアプリケーションで問題になります。 boost::lambdaboost::parameterもご覧ください。

0

私はあなたがC++のvarargsのような省略記号を必要としていると思います。

1

Boostライブラリ(www.boost.org)を使用している場合は、特に興味のあるBoot.BindとBoost.Functionがあります。私は過去にあなたが話していることの線に沿って何かを達成するためにそれらを使ってきました。

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

MV

0

おそらく、std :: tr1 ::関数が面白いですか?

1

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

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

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

+0

これは意味があります。クラスを作成し、それを渡すメインクラスは、どの型のファンクタか、それ以外のファンクタを受け取るクラスを知り、単にoperator()メソッドを呼び出します。情報のおかげで訪問者のパターンを調べます。 –

1

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

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パターンでは達成できなかったこのアプローチで何が達成できるのかよくわかりません。