最近開始寫一個線程池,期間想用一個通用的函數模板來使得各個線程執行不同的任務,找到了Boost庫中的function函數。
Boost::function是一個函數包裝器,也即一個函數模板,可以用來代替擁有相同返回類型,相同參數類型,以及相同參數個數的各個不同的函數。
1 #include<boost/function.hpp>
2 #include<iostream>
3 typedef boost::function<int(int ,char)> Func; 4
5 int test(int num,char sign) 6 { 7 std::cout<<num<<sign<<std::endl 8 } 9
10 int main() 11 { 12 Func f; 13 f=&test; //or f=test
14 f(1,'A'); 15 }
這樣在不同的地方用不同的函數來替代 f 可以得到類似於C++中多態的效果。
但是這樣有一定的局限性,例如我想實現的線程池需要執行不同的任務,這些任務的返回類型,函數參數個數,參數類型肯定是不同的,所以不能用上面的方法實現,那么怎么樣定義一個函數模板來包含各種返回類型,函數參數個數,參數類型不同的各種函數呢?
我們可以定義如下的類型
1 typedef boost::function<void()> Func; 2 //or 3 typedef boost::function<void(void)> Func;
void 類型(空類型)其實是C中四種數據類型之一,其余三個為基本類型,構造類型,指針型。
空類型主要是用來修飾返回類型與函數參數的,不能用了定義變量,void i 是錯誤的。
可以這樣認為空類型是一個抽象的基類,不能用了定義變量,但是它可以表示所有的類型,這樣也不難理解,void* 指針能夠不用強制轉換成不同類型的指針了。
void類型的返回類型表示我們可以返回各種不同的類型了,那我們怎么樣傳入參數呢?可以用boost::bind。
1 #include<boost/function.hpp>
2 #include<boost/bind.hpp>
3 #include<iostream>
4 typdef boost::function<void(void)> Func; 5
6 int test(int num) 7 { 8 std::cout<<"In test"<<std::endl; 9 } 10
11 int main() 12 { 13 Func f(boost::bind<test,6>); 14 f(); 15 }
使用bind來傳入各個參數,形成一個通用的函數模板。
不過由於f()的返回值是void類型,所以我們不能有以下寫法:
1 int result=f(); 2 //or 3 std::cout<<f()<<std<<endl;
不過沒有關系,我們可以從參數中傳出結果。