2011-04-30 120 views
2

我有綁定參數功能的問題。調用者類調用函數,它不知道參數。所以我不能像結合使用佔位符:綁定參數

v.invoke(boost::bind(&B::fun, this, _1)); 

我想讓這樣的事情:

v.invoke(boost::bind(&B::fun, this, fun_p)); 

我需要它,因爲我想通過功能A::funB::BFunB::BFun不應直接撥打A::fun,而應使用B::fun

class A 
{ 
public: 
A(){} 
    void fun(){ 
     std::wcout << "FunA" << std::endl; 
    } 
}; 

class Invoker 
{ 
public: 
    Invoker(){} 
    template <typename Handler> 
    void invoke(Handler f) 
    { 
    f(); 
    } 
}; 


class B 
{ 
public: 
B(){} 

template <typename Handler> 
void BFun(Handler fun_p) 
{ 
    Invoker v; 
    v.invoke(boost::bind(&B::fun, this, fun_p)); <------- how to pass param. Not  placeholder 
} 

template <typename Handler> 
void fun(Handler func) 
{ 
    func(); 
    std::wcout << "FunB" << std::endl; 
} 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
A a; 
B b; 
b.BFun(boost::bind(&A::fun, &a)); 
return 0; 
} 

回答

1

問得好!

這裏有兩個問題。

問題1:傳遞bind當作爲參數來bind,會得到一個函數組合:內結合的結果被評估,並傳遞給外綁定作爲一個參數。請參閱documentation。爲了解決這個問題,你應該protect包裝你的功能參數:

template <typename Handler> 
void BFun(Handler fun_p) 
{ 
    BFunImpl(boost::protect(fun_p)); 
} 

template<tyename Handler> 
void BFunImpl(Handler fun_p) 
{ 
    Invoker v; 
    v.invoke(boost::bind(&B::fun, this, fun_p)); 
} 

問題2:你把一個函數模板的地址。編譯器不知道要實例化哪個函數並獲取地址。您可以使用static_cast以投你所需要的類型,或者使用顯式語法:

v.invoke(boost::bind(&B::template fun<Handler>, this, fun_p)); 

現在,它編譯罰款。

+0

不錯。我的例子很難理解這一點。但是,謝謝。我認爲它不那麼複雜。 – userbb 2011-04-30 16:24:01

+0

我不明白問題1.功能組成在哪裏? – userbb 2011-04-30 16:57:00

+0

@userbb:'main'用'bind(&A :: fun,&a)'作爲參數'fun_p'調用'BFun'。因此,直接將它替換爲'BFun',你會發現'BFun'內的表達式等同於'bind(&B :: fun,this,bind(&A :: fun,&a))'。這是綁定嵌套,被實現視爲特殊情況。 – ybungalobill 2011-04-30 17:02:00