日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

boost bind使用指南

發布時間:2025/3/21 编程问答 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 boost bind使用指南 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

bind - boost

頭文件: boost/bind.hpp

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

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

9.1 對于普通函數

假如有函數 fun() 如下:
?void fun(int x, int y) {
??cout << x << ", " << y << endl;
?}
現在我們看看怎么用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 {
??void operator()(int x) {
???cout << x << endl;
??}
?} f;
綁定的時候可能要指出返回值的類型:
?boost::bind<void>(f, 3)();? //指出返回值的類型 void
?

9.2 對于非靜態成員函數

假如有:
?struct A {
??void func(int x, int y) {
???cout << x << "," << y << endl;
??}
?};
?
?A a;?
?A* pa = new A;?//指針
?boost::shared_ptr<A> ptr_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 {
??string name_;
??int age_;
?public:
??int get_age();
??string name();
?};

?vector<Personal_info> vec;
?...
現在要對 vec 排序. 可以用 bind 函數做一個比較謂詞
?std::sort(?
??vec.begin(),?
??vec.end(),?
??boost::bind(
???std::less<int>(),???
???boost::bind(&personal_info::age,_1),???? //_1 占位符是 sort 中調用比較函數時的第一個參數.
???boost::bind(&personal_info::age,_2)));?? //_2 占位符是 sort 中調用比較函數時的第二個參數.


9.4 函數組合

假如有:
?vector<int> ints;
?...
想用 std::count_if() 來求ints中有多少是 >5 且 <=10 的. 這在常規代碼中通常就要寫一個函數來實現這個謂詞:
?if (i>5 && i<=10) ...
現在用bind則可以:
?std::count_if(?
??ints.begin(),? ints.end(),?
??boost::bind(???
???std::logical_and<bool>(),???
???boost::bind(std::greater<int>(),_1,5),???
???boost::bind(std::less_equal<int>(),_1,10)));

?

9.5 綁定到成員變量

有:
?map<int, string> my_map;
?my_map[0]="Boost";my_map[1]="Bind";
現在要輸出所有元素的 second 成員. 也就是輸出這些字符串. 其中的打印函數如下:
?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<int,std::string>::value_type::second,_1)
???)
??);
??
汗... 看不懂bind的源碼. 也不知是如何實現這些功能的. 只能等<<boost源碼剖析>>出來了.


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

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

有函數:
void f(int & x) { ++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::vector<pf> v;? //v中有一些函數指針.
std::for_each(v.begin(), v.end(), bind(_1, 5));??
//想實現 _1(5);? 這樣的調用. 但這樣不行!

正確的做法是借助 boost::apply 模板(來自boost/bind/apply.hpp).??
apply也是一個函數對象. 它的作用如下:
apply<void>?a;?? //模板參數為函數對象的返回值類型.
a(x);?????? //相當于調用 x();
a(x, y);??? //相當于調用? x(y);
a(x, y, z);? //相當于調用 x(y, z);
所以錯誤的bind應該寫為:
std::for_each(v.begin(), v.end(), bind(apply<void>(), _1, 5));

總結

以上是生活随笔為你收集整理的boost bind使用指南的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。