任意の戻り値型と任意のパラメーターを持つ派生Functor
-
05-07-2019 - |
質問
仕事の単位としてファンクターを使用するクラスがあります。 Run()メソッドでファンクターへの参照を受け入れます。このクラスが任意のファンクターで動作できるようにするには、これらのファンクターはすべて、次のような基本ファンクタークラスから派生する必要があります。
class baseFunctor{
public:
virtual void operator()()=0;
virtual baseFunctor Clone()=0;
};
これは機能しますが、明らかにこれらのファンクターは、voidを返し、パラメーターを受け入れない演算子メソッドを持つことに制限されます。私はクラスのファンクターを受け入れることができる必要があります。ファンクターはあらゆるタイプのパラメーターを取り、何でも返すことができます。どうやらできるように見えますが、私はそれを行う方法を見つけることができないようです。テンプレート、多重継承を使用することを検討しましたが、このファンクターを実行する必要があるクラスは任意の型を受け入れる必要があるため、基本クラス型を受け入れるため、実際の型がわからないという事実に妨げられ続けますファンクターの。
どのアベニューを見るべきかについての提案はありがたいです。
解決
ファンクターを呼び出すクラスは、どのパラメーターを提供し、戻り値があればそれをどうするかをどのようにして知るのですか?
他のヒント
したがって、この権利を読んでいる場合、「訪問者パターン」があります。見上げるのは良いことかもしれません。
誰かは、ファンクターが引数を与えるためにどのタイプであるかを知る必要があります。多くの場合、ファンクターを使用すると、引数は派生クラスのフィールドに割り当てられ、operator()はそれらのフィールドを操作します。つまり、ファンクターを呼び出してそれについて何も知らないダムメソッドには、より知識のある誰かがクロージャー(メソッドと引数をすべて1つのクラスで)を与えます。
operator()で複数の引数を取る汎用ファンクターが必要な場合は、テンプレート化によって途中まで到達しますが、アリティごとに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パターンではこれほど簡単に達成できないこのアプローチで何が達成できるかはわかりません。
Boostライブラリ(www.boost.org)の使用にオープンである場合は、Boot.BindおよびBoost.Functionが特に興味深いことがあります。過去にそれらを使用して、あなたが議論していることに沿って何かを達成しました。
Boost.Bindを使用する場合、ファンクターが期待する引数の数とRunメソッドが期待する引数の数(つまりゼロ)の差を考慮して、ファンクターをカリー化できます。ファンクタを作成するコードは、引数を特定の値にバインドする必要があるため、Run()に渡すことができる引数なしのファンクタを作成する必要があります。
MV
ファンクタを返すのはなぜですか?何らかの状態も保存していますか?正確にあなたが何をしたいのかはあまり明確ではないので、もう少し詳細に感謝します。
継承を使用する場合は、共変の戻り値の型(および仮想コンストラクタイディオム)。
今、問題の核心について:問題は本当にファンクターを渡すことではなく、ファンクターのアプリケーションにあります。 boost:をご覧ください。 lambda
および boost :: parameter
も同様です。
C ++のvarargsのような省略記号引数が必要だと思います。
おそらくstd :: tr1 :: functionはあなたにとって興味深いですか?