午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

boost bind使用指南(轉(zhuǎn))

 怎么了啊早上 2014-08-13

boost bind使用指南

bind - boost

頭文件: boost/bind.hpp

bind 是一組重載的函數(shù)模板.
用來向一個(gè)函數(shù)(或函數(shù)對(duì)象)綁定 某些參數(shù).
bind的返回值是一個(gè)函數(shù)對(duì)象.

它的源文件太長(zhǎng)了. 看不下去. 這里只記下它的用法:

9.1 對(duì)于普通函數(shù)

假如有函數(shù) fun() 如下:
 void fun(int x, int y) {
  cout << x << ", " << y << endl;
 }
現(xiàn)在我們看看怎么用 bind 向其綁定參數(shù).
對(duì)于像 fun 這樣的普通函數(shù). 若fun 有n個(gè)參數(shù). 則 bind 需要 n+1 個(gè)參數(shù): 原始函數(shù)的地址 以及 n個(gè)要綁定的參數(shù).

第 1種用法:
向原始函數(shù) fun 綁定所有的參數(shù)
 boost::bind(&fun, 3, 4)     // bind的實(shí)參表依次為: 要綁定的函數(shù)的地址, 綁定到fun的第一個(gè)參數(shù)值, 第二個(gè)參數(shù)值...
        // fun有多少個(gè)參數(shù), 這里就要提供多少個(gè).
表示將 3 和 4 作為參數(shù)綁定到 fun 函數(shù).
因?yàn)榻壎怂械膮?shù). 現(xiàn)在我們調(diào)用bind所返回的函數(shù)對(duì)象:
 
boost::bind(&fun, 3, 4)( );  //無參數(shù).
就 會(huì)輸出 3, 4

第 2種用法:
向原始函數(shù) fun 綁定一部分參數(shù)
 boost::bind(&fun, 3, _1)    // bind的實(shí)參表依次還是: 要綁定的函數(shù)的地址, 要綁定到fun的第一個(gè)參數(shù)值, 然后注意
        // 因?yàn)槲覀儾淮蛩阆騠un綁定第2個(gè)參數(shù)(即我們希望在調(diào)用返回的Functor時(shí)再指定這個(gè)參數(shù)的值)
        // 所以這里使用 _1 來占位. 這里的 _1 代表該新函數(shù)對(duì)象被調(diào)用時(shí). 實(shí)參表的第1個(gè)參數(shù).
        // 同理下邊還會(huì)用到 _2 _3 這樣的占位符.
這里只為fun綁定了第一個(gè)參數(shù)3. 所以在調(diào)用bind返回的函數(shù)對(duì)象時(shí). 需要:
 boost::bind(&fun, 3, _1)(4);  //這個(gè)4 會(huì)代替 _1 占位符.
輸出 3, 4
同理 boost::bind(&fun, _1, 3)(4);
輸 出 4, 3

第 3種用法:
不向 fun 綁定任何參數(shù)
 boost::bind(&fun, _1, _2)   // _1 _2 都是占位符. 上邊已經(jīng)說過了.
所以它就是 將新函數(shù)對(duì)象在調(diào)用時(shí)的實(shí)參表的第1個(gè)參數(shù)和第2個(gè)參數(shù) 綁定到fun函數(shù). 
 
boost::bind(&fun, _1, _2)(3, 4);    // 3將代替_1占位符, 4將代替_2占位符.
輸出 3, 4
同理 boost::bind(&fun, _2, _1)(3, 4);   // 3將代替_1占位符, 4將代替_2占位符.
會(huì) 輸出 4, 3 
同理 boost::bind(&fun, _1, _1)(3);     // 3將代替_1占位符
會(huì)輸 出 3, 3

對(duì)于普通函數(shù)就這些. 對(duì)于函數(shù)對(duì)象. 如:
 struct Func {
  void operator()(int x) {
   cout << x << endl;
  }
 } f;
綁定的時(shí)候可能 要指出返回值的類型:
 boost::bind<<span style="color: rgb(0, 0, 255);">void>(f, 3)();
  //指出返回值的類型 void
 

9.2 對(duì)于非靜態(tài)成員函數(shù)

假如有:
 struct A {
  void func(int x, int y) {
   cout << x << "," << y << endl;
  }
 };
 
 A a; 
 A* pa = new A; //指針
 boost::shared_ptr ptr_a(pa);  //智能指針.
 
現(xiàn)在要向像 A::func 這樣的非靜態(tài)成員函數(shù)綁定.
若A::func有n個(gè) 參數(shù), 則 bind 要有 n+2 個(gè)參數(shù): 指向成員函數(shù)fun的指針, 綁定到this的對(duì)象, n個(gè)參數(shù).
如: 
 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個(gè)參數(shù)是 對(duì)象. 對(duì)象指針. 還是智能指針. bind函數(shù)都能夠正常工作.


9.3 bind嵌套

有個(gè)類如下. 記錄人的信息:
 class Personal_info {
  string name_;
  int age_;
 public:
  int get_age();
  string name();
 };

 vector vec;
 ...
現(xiàn) 在要對(duì) vec 排序. 可以用 bind 函數(shù)做一個(gè)比較謂詞
 std::sort( 
  vec.begin(), 
  vec.end(), 
  boost::bind(
   std::less(),   
   boost::bind(&personal_info::age,_1),     //_1 占位符是 sort 中調(diào)用比較函數(shù)時(shí)的第一個(gè)參數(shù).
   boost::bind(&personal_info::age,_2)));   //_2 占位符是 sort 中調(diào)用比較函數(shù)時(shí)的第二個(gè)參數(shù).


9.4 函數(shù)組合

假如有:
 vector ints;
 ...
想 用 std::count_if() 來求ints中有多少是 >5 且 <=10 的. 這在常規(guī)代碼中通常就要寫一個(gè)函數(shù)來實(shí)現(xiàn)這個(gè)謂詞:
 if (i>5 && i<=10) ...
現(xiàn)在用 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 綁定到成員變量

有:
 map my_map;
 my_map[0]="Boost";my_map[1]="Bind";
現(xiàn)在要輸出所有元素的 second 成員. 也就是輸出這些字符串. 其中的打印函數(shù)如下:
 void print_string(const string& s) { 
  std::cout << s << '\n';
 }
則可以:
 for_each( 
  my_map.begin(), 
  my_map.end(), 
  boost::bind(
   &print_string,
   boost::bind(&std::map::value_type::second,_1)
   )
  );
  
汗... 看不懂bind的源碼. 也不知是如何實(shí)現(xiàn)這些功能的. 只能等<<boost源碼剖析>>出來了.


 注意:
(以下補(bǔ)于08年6月3日)

boost::bind() 返回的函數(shù)對(duì)象會(huì)保存要綁定的實(shí)參. 而且總是拷貝一份以值的方式保存..
這主要是考慮到被綁定的實(shí)參的生命期.  
但這并不總 是我們期望的. 例如有時(shí)我們希望它保存指針或引用:

有函數(shù):
void f(int & x) { ++x; }
然 后:
int n = 0;
bind(&f, n)();    //我們希望 n==1 . 但實(shí)際上沒有這樣...

要 避免這種對(duì)象復(fù)制.  
要bind得到的函數(shù)對(duì)象保存實(shí)參的引用語(yǔ)義. 可以:
使用 boost::ref()  或 boost::cref() 如
bind(&f, ref(n))();        //OK,  執(zhí)行后 n==1

如 果是綁定一個(gè)對(duì)象到它的成員函數(shù)上. 如:
A a;
bind(&A::fun, a);       //則保存的是 a對(duì)象的拷貝.
要避免這種拷貝. 除了上面提到的 ref() 外, 也可以:
bind(&A::fun, &a);      //用指針.  反正用對(duì)象和用指針都可以. 而用指針可以避免對(duì)象拷貝的問題. 



注意: (以下補(bǔ)于6月10日)
bind () 的第一個(gè)參數(shù)——被綁定函數(shù)——是不被求值的. 如下例:

typedef void (*pf)(int);
std::vector v;  //v中有一些函數(shù)指針.
std::for_each(v.begin(), v.end(), bind(_1, 5));  
 //想實(shí)現(xiàn) _1(5);  這樣的調(diào)用. 但這樣不行!

正確的做法是借助 boost::apply 模板(來自boost/bind/apply.hpp).  
apply也是一個(gè)函數(shù)對(duì)象. 它的作用如下:
apply a;   //模板參數(shù)為函數(shù)對(duì)象的返回值類型.
a(x);       //相當(dāng)于調(diào)用 x();
a(x, y);    //相當(dāng)于調(diào)用  x(y);
a(x, y, z);  //相當(dāng)于調(diào)用 x(y, z);
所以錯(cuò)誤的bind應(yīng)該寫為:
std::for_each(v.begin(), v.end(), bind(apply(), _1, 5));

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多