boost::bind的使用

http://blog.csdn.net/hopingwhite/article/details/6278472

最近在幾經波折之後,終於對於boost::bind有點理解了。對於習慣了其他語言的人來說,boost::bind是個挺神奇的東西,它可以將你的方法適配成任何其他的方法。其實這得益於c++的模板以及操作符重載,去看boost::bind的實現就會發現它是一個有n多重載的函數,這些重載主要是爲了適應函數的參數個數。

 

其實boost::bind的原理是函數對象,而函數對象就是一個重載了()操作符的對象,這樣我們就可以像調用一個方法一樣來調用一個類上的這個操作符,比如a(),其實你是在調用a這個對象的()方法,而不是調用一個叫a的方法。

 

一般來說boost::bind有兩種方式的調用,一種是對自由方法,也取非類方法, 一種是對類方法。

 

對自由方法來說,直接boost::bind(函數名, 參數1,參數2,...)

對類方法來說,直接boost::bind(&類名::方法名,類實例指針,參數1,參數2)

 

這裏需要額外注意的問題是,函數對象也可以像自由方法一樣被bind,而boost::function也是一種函數對象。

 

接下來我們需要注意什麼情況下需要用_1, _2這樣的參數。

 

舉個例子

void test(int a, int b, int c)

 

boost::bind(test, 1, _1, _2)得到一個函數對象b,當我們調用b(3,4)時,相當於調用test(1,3,4)

boost::bind(test, _2, 3, _1)得到一個函數對象b,當我們調用b(3,4)時,相當於調用test(4,3,3)

 

看明白了沒有?你實際上可以指定一些常量和一些佔位符進去,_x這樣的就是佔位符,_1表示實際調用時的參數位置,也即b(3,4)時_1代表3,_2代表4

 

當然你也可以將所有的參數都指定

比如boost::bind(test,1,2,3),那麼在調用b()時就相當於調用test(1,2,3)

 

需要注意的一點是,boost::bind裏的參數個數一定要與被bind的函數相同,否則這個函數對象就無法生成了,編譯器會抱怨一堆信息,如果你仔細看的話,它是在告訴你,沒有這樣的函數,你實際的函數是....,這是使用c++很杯具的一點,當遇到模板時,一旦報錯,那些信息直接可以令人崩潰。

 

在asio中,boost::bind被大量使用,原因是異步的情況下,每個函數的調用是獨立的,它的所有信息應該包含在它的調用,也即函數對象中。因此asio中有大量的模板,如果在這種情況下你想要使用虛函數或者繼承來寫框架的話,會是一件很杯具的事情,在碰了很多次壁之後,我發現其實很多情況下我並不需要純虛函數,我需要的只是一個函數指針,或者函數對象而已。


[cpp]  

int f(int a, int b)  
{  
    return a + b;  
}  
  
int g(int a, int b, int c)  
{  
    return a + b + c;  
}  
  
// 函數指針定義  
typedef int (*f_type) (int, int);  
typedef int (*g_type) (int, int, int);  
  
// 使用struct僅僅是爲了方便, 不必寫出public  
struct demo  
{  
    int f(int a, int b)  
    {  
        return a + b;  
    }  
};  
  
// 函數對象  
struct sf   
{  
    int operator()(int a, int b)  
    {  
        return a + b;  
    }  
};  
  
void test_bind_common()  
{  
    std::cout << boost::bind(f, 1, 2)() << std::endl;  
    std::cout << boost::bind(g, 1, 2, 3)() << std::endl;  
}  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章