2011-08-05 9 views
3
class Foo 
{ 
    double f1(int x, std::string s1); 
    double f2(int x, SomeClass s2); 
} 

私はその後、私は他の関数へのパラメータとして関数func1とfunc2のを渡すエッセンスでブーストバインドクラス関数ポインタ

typedef double (Foo::* MyFooFunc)(int) 

MyFooFunc func1 = boost::bind(&Foo::f1, _1, _2, "some string"); 
MyFooFunc func2 = boost::bind(&Foo::f2, _1, _2, SomeClass); 

を作成するためのfooのインスタンスなしFoo.f1のS1をバインドできるようにしたいです、その内側にはFooは最終的にバインドされます。

void SomeOtherFunction(MyFooFunc func) 
{ 
    Foo foo; 
    boost::function< double (int) > finalFunc = 
      boost::bind(func, foo, _1); 
} 

質問: はこの可能ですか?はい、1)それを達成する方法? 2)MyFooFuncの宣言は何ですか?

+0

それはSomeOtherFunction'が宣言されている 'に依存する(再度、他のboost::functionタイプは、REF対非constとは対照的に、REF対CONSTを渡すなどの詳細に応じて可能です) 。あなたの2番目のtypedefは関数ポインタではなく、それは全く別の互換性のない概念であるPTMF(pointer-to-member-function)です。 'std :: function'や' std :: tr1 :: function'や 'boost :: function'の全てをラップするのがおそらく最も強力な解決策です。 –

+0

実際には2つの問題があります。1)インスタンスなしでPTMFをバインドする。 2)ブースト関数としてバインドの結果を表現する。 1)のために、boost :: bind(&Foo :: f1、_1、_2、 "hello")を試しました。それはうまくいかなかった。 2)については、boost :: function 、int)>と思われます。 –

答えて

4
typedef double (Foo::* MyFooFunc)(int); 

MyFooFunc func1 = boost::bind(&Foo::f1, _1, _2, "some string"); 

boost::bindの結果は、メンバーへのポインタではないので、func1は、第二のライン上のような初期化することができません。 boost::bindの結果は、指定されていない型です(パラメータによって異なります)。あなたがC++ 0xのを使用している場合は、bindに呼び出しの結果を命名する最も簡単な方法は、autoを使用することです:

auto func1 = boost::bind(&Foo::f1, _1, _2, "some string"); 

もう一つの簡単な方法(C++ 03に限定されない)が、単純にではありません結果に名前を付けますが、その場でそれを使用する:

SomeOtherFunction(boost::bind(&Foo::f1, _1, _2, "some string")); 

それとも、あなたが精通しているように見えるboost::functionboost::bindの結果を保存するために、型消去を使用することができます。 boost::function<double(Foo&, int)>は可能ですが唯一の選択肢ではありません。


現在SomeOtherFunctionのための適切な署名を見つける必要がある:再び、メンバへのポインタはboost::bindに呼び出しの結果から初期化することはできませんので、void SomeOtherFunction(MyFooFunc func);は動作しません。代わりに、テンプレート機能を行うことができます。

template<typename Func> 
void SomeOtherFunction(Func func) 
{ 
    Foo foo; 
    boost::function< double (int) > finalFunc = 
      boost::bind(func, foo, _1); 
} 

テンプレートがpreferrableない場合、あなたは、このようなboost::function、再び、など種類消去のいくつかの種類を使用する必要があります。

void SomeOtherFunction(boost::function<double(Foo&, int)> const& func); 

+0

パーフェクト、ありがとう。 –

0

これを試してみてください:

boost::bind(&Foo::f1, object, _1, _2); 

objectは、Fooクラスのインスタンスです。 _1と_2が引数プレースホルダです。

+0

OPには 'Foo :: f1(int)'が必要なので、たぶん1つのプレースホルダがあります。 –

+0

'object'がポインタではなく値であれば、' boost :: ref(object) 'や'&object'を実行する必要があります。そうでなければバインダはコピーに対して動作します。 –

+0

混乱して申し訳ありません。私はFoo(オブジェクト)のインスタンスと非一様なパラメータ(s1、s2)のバインドを2つのステップに分けたいと思います。 –