程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> Boost庫bind函數的嵌套調用

Boost庫bind函數的嵌套調用

編輯:C++入門知識

問題提出:
我寫了一個函數,它需要使用一個生成整數隨機數的隨機數發生器作為參數。然後寫了一個函數來根據參數生成不同分布的隨機數發生器,供前一個函數使用。我調用了boost庫的一些基於特定概率分布的隨機數生成函數,但是有很多函數的結果是double型的。

我的函數將隨機數發生器定義為boost::function<int()>類型。很明顯那些生成double的函數不能直接通過bind operator()的方式得到,而需要類型轉換。而這個使用bind/function的嵌套調用就比較麻煩了。

 


假設我有兩個函數:


[cpp]
int trans(double); 
double gen(); 

int trans(double);
double gen();
我希望的結果是得到一個函數對象:它使用gen生成原始數字,然後用trans函數把它轉成整形返回;即得到一個這樣的函數:


[cpp]
int fun(){ 
    return trans(gen()); 

int fun(){
    return trans(gen());
}

 

我這裡還是無參數的,所以不好使用lambda表達式。

最終方案與要點:
這個問題解決好久,心酸啊,過程就略過了,直接說最終方法。
假設使用前面的函數聲明,那麼這個函數對象應該這麼生成:

[cpp]
boost::function<int()> fun=boost::bind(trans,boost::bind(gen)); 

boost::function<int()> fun=boost::bind(trans,boost::bind(gen));

其中要使用兩次bind!

內層的那個看似沒什麼用,但是如果不適用它的話,boost不會以為我們要綁定的第一個參數是一個函數,而是以為我們要綁定一個具體的值,這個數字的值由這個gen函數產生。這時編譯器會報“無法將double(void)類型轉換為double類型”的錯誤。

 


同樣的其他參數形式的(需要使用lambda庫)、多層的函數嵌套綁定,都應該注意要把內層的函數通過bind變成一個可傳遞的對象,而不能直接寫函數名!

bind綁定的各個東西都是對象(包括基本數據類型),是不支持把參數直接綁定為函數的,要這邊做必須先把函數變成可以自由傳遞的對象!

另外不要以為你的參數已經是函數對象了就可以直接寫了,還要再寫bind(),具體原因還不清楚。

 


其他經驗:
1,static_cast<T>()是運算符而不是函數!所以不能綁定。

2,boost/lambda/casts.hpp提供的ll_static_cast<T>雖然是函數,但是需要注意的是它是有兩個模板參數的模板函數,在綁定的時候我們不能給出參數的實際類型(外側的bind函數給ll_static_cast提供的是funnction<int()>的類型而不是int),因而也不能使用ll_static_cast,要自己寫轉換函數。

3,bind和lambda/bind有沖突,而且很多功能重疊,用一個就好了。


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved