2011-10-26 7 views
7

ように私はそうのようなメソッドを介してのstd ::関数を渡すしようとしています:C++ 0xのはstd ::機能メソッドの引数

class dispatch 
{ 
    public: 
    deliver(std::function<void (void)> task); 
} 

予想通り、この作品。しかし、私はタスクとして提供されたメソッドのいくつかに引数を渡したいが、すべての異なる関数< ...>フォームに対してオーバーロードを作成する必要はありません。例えば

は、それが

deliver(std::function& task); 

を次のようにすべての可能なだけでメソッドを作成すると、ちょうど...

dispatch->deliver(bind(&Object::method, X)); 

または

dispatch->deliver(bind(&Object::method, X, arg1, arg2)); 

などで呼び出しています

ありがとうすべての入力に対して。私の本当の欠点は、ディスパッチ - >引き渡しを呼び出して、バインドコールでもある追加の引数を渡すことです。

dispatch->deliver(bind(&Object::method1, X1, bind(&Object::method1, X2)); 

error: /usr/include/c++/v1/functional:1539:13: error: no matching function for call to '__mu_expand' return __mu_expand(__ti, __uj, __indices());

+0

クラス宣言の後に ';'がありません。 :-) –

答えて

9

std::function<void(void)>それはそれの全体のポイントですが、すでに多型です。したがって、最後の2つのスニペットが機能します(ファンクタbindの戻り値は引数なしで呼び出すことができ、何も返しません)。

3

はい、それは限り、あなたは互換性のある関数オブジェクトを生成するためにバインドを使用して可能である:

#include <boost/bind.hpp> 
#include <boost/function.hpp> 
#include <iostream> 
#include <list> 
#include <string> 

typedef boost::function<void(void)> fun_t; 
typedef std::list<fun_t> funs_t; 

void foo() 
    { std::cout <<"\n"; } 
void bar(int p) 
    { std::cout<<"("<<p<<")\n"; } 
void goo(std::string const& p) 
    { std::cout<<"("<<p<<")\n"; } 

void caller(fun_t f) 
    { f(); } 

int main() 
{ 
    funs_t f; 
    f.push_front(boost::bind(foo)); 
    f.push_front(boost::bind(bar, int(17))); 
    f.push_front(boost::bind(goo, "I am goo")); 

    for (funs_t::iterator it = f.begin(); it != f.end(); ++it) 
    { 
     caller(*it); 
    } 

    return 0; 
} 

(私はBoost.FunctionとBoost.Bind使用していますが、で使用するためには差があってはならない、注意してくださいstd :: bindとstd :: function)

+0

'fun_t'を値や参照で渡すのが好きでしょうか? – hkBattousai

+0

@hkBattousaiそれは異なります。 http://stackoverflow.com/a/8711486/151641およびhttp://stackoverflow.com/a/18366273/151641を参照してください。 – mloskot

1
class dispatch 
{ 
    public: 
    template <typename ... Params> 
    deliver(std::function<void (Params && p...)> task, Params && p) 
    { 
     task(std::forward(p)...); 
    } 
}; 

私はこれを編集していませんが、このアイデアはうまくいくはずです。

dispatch->deliver(bind(&Object::method, X)); 
dispatch->deliver(bind(&Object::method, X, arg1, arg2)); // OR! 
dispatch->deliver(bind(&Object::method, X), arg1, arg2); 

私は程度は不明だ一つのことはObject::methodではなく、過負荷ののparamsをデフォルトした場合、これはどのように動作するかです。

+0

+1:1つのニックピット、std :: functionをconst参照として渡す方が効率的かもしれません。 。 – mirk

+0

@DirkMあなたは正しいですが、OPはそれをしなかったので、私もそれほど選びませんでした。彼は、 "配送"に関与していない配送方法で何かをしている可能性があります。私は思っていません。 –

関連する問題