2009-03-23 10 views
2

オブジェクトへのポインタと、ファンクタがboost :: functionを使って構築したファンクタからどのメソッドを呼び出すかの指示を取得したいと思いますブースト::バインド これにより、どのファンクタを実行する必要があるかを自動的に判断することができます。boost :: functionとboost :: bindを使ってファンクタのオブジェクトとメソッドを決定する

以下の(擬似)コード(参照POINTER_OF & METHOD_OFは)私が何をしようとしているを示しています。事前に

class myClassA 
{ 
    public: 
    DoIt(int i) { return i+i; } 
}; 

class myClassB 
{ 
    public: 
    DoItToo(double d) { return d*d; } 
}; 

typedef boost::function0<int> Functor; 

myClassA classA; 
myClassB classB; 

Functor funcA = boost::bind(&myClassA::DoIt, &classA, 10); 
Functor funcB = boost::bind(&myClassB::DoItToo, &classB, 12.34); 

// Create a vector containing some functors and try to determine the objects 
// they are called upon and the methods they invoke 
std::vector<Functor> vec; 
vec.push_back(funcA); 
vec.push_back(funcB); 

for (int i = 0; i < vec.size();i++) 
{ 
    if (POINTER_OF(vec[i]) == &classA) 
    { 
    // This functor acts on classA 
    if (METHOD_OF(vec[i]) == &myClassA::DoIt) 
    { 
     // This functor calls the 'DoIt' method. 
    } 
    else if (METHOD_OF(vec[i]) == &myClassB::DoItToo) 
    { 
     // This functor calls the 'DoItToo' method. 
    } 
    } 
    // etc... 
} 

感謝を!

+0

コードあなたが書いたものは醜いです。ごめんなさい。あなたはポインタとメソッドに関する情報をどうしたらいいのですか? – bayda

+0

いくつかのスタイルアドバイス、 "classA"という名前を変更しました。これはクラスではなく、特定のクラスのインスタンスであるオブジェクトです。 "instanceA"は問題ありません。 "instanceOfClassA"は特に冗長ですが、少なくとも正確です。 – Aaron

答えて

4

私は次のことはあなたの質問に厳しい答えではないことを知っています。

これを行わないでください。 多態性を代わりに使用してください。私の現在のプロジェクトコードで見た最も奇妙なことの1つです:関数ポインタが "someFunction"を指している場合 - いくつかの追加のアクションを行います。

デコレータデザインパターンでクラスを変更することなく、余分な動作を追加できます。それはあなたのmyClassA :: DoItをDecorator :: DoItで拡張します。

http://en.wikipedia.org/wiki/Decorator_pattern

+0

多分私の例は明確ではありません;-)私は、メソッドの実行順序を決定するために、多数のファンクタのために呼び出されるオブジェクトとメソッドを決定する必要があります。機械制御で - オブジェクトは物理的システムを表す) –

+0

@lasser - それはMykolaの答えの良さを変えない。優先度と機能を持つオブジェクトのリストが必要です。 –

0

いいえ、私はあなたがブーストバインド(すなわちMETHOD_OF)に設定されているブースト機能のターゲットを得ることができるとは思いません。ブーストメーリングリストのthis postによると、これはバインドの戻り値の型が形式的に指定されていないためです。

編集:リンクこの質問に関連するいくつかの、何でそれ以前の質問に:demote-boostfunction-to-a-plain-function-pointer

0

boost::functionオブジェクトは平等同等であるので、あなたは

if (vec[i] == boost::bind(&myClassA::DoIt, &classA, 10)) 
{ 
    // ... this Functor calls DoIt on classA with argument 10 
} 

のようなものを行うことができるはず私は疑いますあなたはもっと一般的な何かを探しています。 boost/function_equal.hpp(つまりboost::bindfunction_equal_impl)の実装の詳細を調べると、boost::bind引数のサブセットを選択的にテストする方法がわかります。

しかし、私は本当にあなたは多相性ベースのソリューションを使い、あるいは関数オブジェクトをメタデータで集約するほうが良いと思います。

+0

コメントありがとう、timday。もし私が正しく理解したら、equal_implを使うと、オブジェクトとメソッドをboost :: bindから取り除くという問題に直面します。boost :: bindインスタンスの比較は、異なるパラメータが渡されたときに異なっているので動作しません。 –

+0

等価性テストの実装自体は、オブジェクトとメソッドにアクセスする必要があります(比較するため)。そのため、これらの実装方法を検討することをおすすめします。 – timday

関連する問題