boost bind使用指南

2021-05-25 04:58:03 字數 4153 閱讀 3245

bind - boost

標頭檔案: boost/bind.hpp

bind 是一組過載的函式模板.

用來向乙個函式(或函式物件)繫結某些引數.

bind的返回值是乙個函式物件.

它的原始檔太長了. 看不下去. 這裡只記下它的用法:

9.1 對於普通函式

假如有函式 fun() 如下:

void fun(int x, int y)

現在我們看看怎麼用bind 向其繫結引數.

對於像 fun 這樣的普通函式. 若fun 有n個引數. 則 bind 需要 n+1 個引數: 原始函式的位址 以及 n個要繫結的引數.

第1種用法:

向原始函式 fun 繫結所有的引數

boost::bind(&fun, 3, 4)     // bind的實參表依次為: 要繫結的函式的位址, 繫結到fun的第乙個引數值, 第二個引數值...

// fun有多少個引數, 這裡就要提供多少個.

表示將 3 和 4 作為引數繫結到 fun 函式.

因為繫結了所有的引數. 現在我們呼叫bind所返回的函式物件:

boost::bind(&fun, 3, 4)( );  //無引數.

就會輸出 3, 4

第2種用法:

向原始函式 fun 繫結一部分引數

boost::bind(&fun, 3, _1)    // bind的實參表依次還是: 要繫結的函式的位址, 要繫結到fun的第乙個引數值, 然後注意

// 因為我們不打算向fun繫結第2個引數(即我們希望在呼叫返回的functor時再指定這個引數的值)

// 所以這裡使用 _1 來佔位. 這裡的 _1 代表該新函式物件被呼叫時. 實參表的第1個引數.

// 同理下邊還會用到 _2 _3 這樣的佔位符.

這裡只為fun繫結了第乙個引數3. 所以在呼叫bind返回的函式物件時. 需要:

boost::bind(&fun, 3, _1)(4);  //這個4 會代替 _1 佔位符.

輸出 3, 4

同理 boost::bind(&fun, _1, 3)(4);

輸出 4, 3

第3種用法:

不向 fun 繫結任何引數

boost::bind(&fun, _1, _2)   // _1 _2 都是佔位符. 上邊已經說過了.

所以它就是 將新函式物件在呼叫時的實參表的第1個引數和第2個引數 繫結到fun函式. 

boost::bind(&fun, _1, _2)(3, 4);    // 3將代替_1佔位符, 4將代替_2佔位符.

輸出 3, 4

同理 boost::bind(&fun, _2, _1)(3, 4);   // 3將代替_1佔位符, 4將代替_2佔位符.

會輸出 4, 3 

同理 boost::bind(&fun, _1, _1)(3);     // 3將代替_1佔位符

會輸出 3, 3

對於普通函式就這些. 對於函式物件. 如:

struct func

} f;

繫結的時候可能要指出返回值的型別:

boost::bind(f, 3)();  //指出返回值的型別 void

9.2 對於非靜態成員函式

假如有:

struct a

};a a; 

a* pa = new a; //指標

boost::shared_ptrptr_a(pa);  //智慧型指標.

現在要向像 a::func 這樣的非靜態成員函式繫結.

若a::func有n個引數, 則 bind 要有 n+2 個引數: 指向成員函式fun的指標, 繫結到this的物件, n個引數.

如: 

boost::bind(&a::func, a, 3, 4)();    //輸出 3, 4

boost::bind(&a::func, pa, 3, 4)();   //輸出 3, 4

boost::bind(&a::func, ptr_a, 3, 4)();//輸出 3, 4

同樣可以用 _1 這樣的佔位符. 如:

boost::bind(&a::func, _1, 3, 4)(ptr_a);//輸出 3, 4

可以看出. 不論傳遞給bind 的第2個引數是 物件. 物件指標. 還是智慧型指標. bind函式都能夠正常工作.

9.3 bind巢狀

有個類如下. 記錄人的資訊:

class personal_info ;

vectorvec;

...現在要對 vec 排序. 可以用 bind 函式做乙個比較謂詞

std::sort( 

vec.begin(), 

vec.end(), 

boost::bind(

std::less(),   

boost::bind(&personal_info::age,_1),     //_1 佔位符是 sort 中呼叫比較函式時的第乙個引數.

boost::bind(&personal_info::age,_2)));   //_2 佔位符是 sort 中呼叫比較函式時的第二個引數.

9.4 函式組合

假如有:

vectorints;

...想用 std::count_if() 來求ints中有多少是 >5 且 <=10 的. 這在常規**中通常就要寫乙個函式來實現這個謂詞:

if (i>5 && i<=10) ...

現在用bind則可以:

std::count_if( 

ints.begin(),  ints.end(), 

boost::bind(   

std::logical_and(),   

boost::bind(std::greater(),_1,5),   

boost::bind(std::less_equal(),_1,10)));

9.5 繫結到成員變數

有:mapmy_map;

my_map[0]="boost";my_map[1]="bind";

現在要輸出所有元素的 second 成員. 也就是輸出這些字串. 其中的列印函式如下:

void print_string(const string& s)

則可以:

for_each( 

my_map.begin(), 

my_map.end(), 

boost::bind(

&print_string,

boost::bind(&std::map::value_type::second,_1)));

汗... 看不懂bind的原始碼. 也不知是如何實現這些功能的. 只能等<

注意:(以下補於08年6月3日)

boost::bind() 返回的函式物件會儲存要繫結的實參. 而且總是拷貝乙份以值的方式儲存..

這主要是考慮到被繫結的實參的生命期. 

但這並不總是我們期望的. 例如有時我們希望它儲存指標或引用:

有函式:

void f(int & x)

然後:int n = 0;

bind(&f, n)();    //我們希望 n==1 . 但實際上沒有這樣...

要避免這種物件複製.  而要bind得到的函式物件儲存實參的引用語義. 可以:

使用 boost::ref()  或 boost::cref() 如

bind(&f, ref(n))();        //ok,  執行後 n==1

如果是繫結乙個物件到它的成員函式上. 如:

a a;

bind(&a::fun, a);       //則儲存的是 a物件的拷貝.

要避免這種拷貝. 除了上面提到的 ref() 外, 也可以:

bind(&a::fun, &a);      //用指標.  反正用物件和用指標都可以. 而用指標可以避免物件拷貝的問題.

注意: (以下補於6月10日)

bind () 的第乙個引數——被繫結函式——是不被求值的. 如下例:

typedef void (*pf)(int);

std::vectorv;  //v中有一些函式指標.

std::for_each(v.begin(), v.end(), bind(_1, 5));   //想實現 _1(5);  這樣的呼叫. 但這樣不行!

boost bind使用指南

bind boost 標頭檔案 boost bind.hpp bind是一組過載的函式模板.用來向乙個函式 或函式物件 繫結 某些引數.bind的返回值是乙個函式物件.它的原始檔太長了.看不下去.這裡只記下它的用法 9.1 對於普通函式 假如有函式 fun 如下 void fun int x,int...

boost bind使用指南

bind boost 標頭檔案 boost bind.hpp bind 是一組過載的函式模板.用來向乙個函式 或函式物件 繫結某些引數.bind的返回值是乙個函式物件.它的原始檔太長了.看不下去.這裡只記下它的用法 9.1 對於普通函式 假如有函式 fun 如下 void fun int x,int...

boost bind使用指南

bind boost 標頭檔案 boost bind.hpp bind 是一組過載的函式模板.用來向乙個函式 或函式物件 繫結某些引數.bind的返回值是乙個函式物件.它的原始檔太長了.看不下去.這裡只記下它的用法 9.1 對於普通函式 假如有函式 fun 如下 void fun int x,int...