bind是一種非常神奇的存在,它不是一個單獨的類或者函數(shù),依據(jù)綁定的參數(shù)的個數(shù)和要綁定的調(diào)用對象的類型,總共有數(shù)十種不同的形式叛赚,編譯器會根據(jù)具體的綁定代碼制動確定要使用的正確的形式澡绩。
話不多說稽揭,直接上例子說用法。
1.bind綁定普通函數(shù)(函數(shù)指針)
定義函數(shù)
int f(int a,int b)
{
return a + b;
}
int g(int a,int b,int c)
{
return a + b + c;
}
typedef int (*f_pointer)(int,int);
typedef int (*g_pointer)(int,int,int);
調(diào)用范例
//普通函數(shù)
bind(f, 1, 2)(); //f(1,2)
bind(f, _2, _1)(x, y); // f(y, x)
bind(g, _1, 9, _1)(x); // g(x, 9, x)
bind(g, _3, _3, _3)(x, y, z); // g(z, z, z)
bind(g, _1, _1, _1)(x, y, z); // g(x, x, x)
//函數(shù)指針
f_pointer fp = f;
g_pointer gp = g;
bind(pf,_1,9); //(*pf)(x,9)
bind(pg,_3,_2,_2)(x,y,z); //(*pg)(z,y,y)
bind有兩個參數(shù)表肥卡,第一個參數(shù)表是bind綁定的函數(shù)的參數(shù)表(即f和g的參數(shù)表)溪掀,第二個參數(shù)表是bind生成的新的對象的參數(shù)表,其中步鉴,_1,_2…被稱作占位符揪胃,至多可以有9個。
2.bind綁定成員函數(shù)
類的成員函數(shù)必須通過類的對象或者指針調(diào)用氛琢,因此在綁定時喊递,bind要拿出第一個參數(shù)的位置來指定一個類的實例、指針或者引用阳似。
class demo
{
public:
int f(int a,int b){return a + b;}
};
demo a,&ra = a; //類的實例對象和引用
demo * p = & a; //指針
bind(&demo::f,a,_1,20)(10); //a.f(10,20)
bind(&demo::f,ra,_2,_1)(10,20); //a.f(20,10)
bind(&demo::f,p,_1,_2)(10,20); //p->f(10,20)
注意:必須在成員函數(shù)前面加上取地址的操作符&骚勘。
再舉一個例子:
bind搭配標(biāo)準(zhǔn)算法for_each用來調(diào)用容器中所有對象的print()函數(shù)
#include <boost/bind/bind.hpp>
using namespace boost;
struct point
{
int x,y;
point(int a = 0,int b = 0):x(a),y(b){}
void print()
{
cout << " ( " << x << " , " << y << " ) \n ";
}
};
int main()
{
vector<point> v(10);
for_each(v.begin(),v.end(),bind(&point::print,_1));
}
這里的for_each()函數(shù)的作用是變量v中從begin開始到end結(jié)束,每一個成員都要調(diào)用print()函數(shù)。
3.bind綁定成員變量
bind可以綁定類中的public成員變量俏讹,依然用point類來說明当宴。
#include <boost/bind/bind.hpp>
using namespace boost;
struct point
{
int x,y;
point(int a = 0,int b = 0):x(a),y(b){}
};
int main()
{
vector<point> v(10);
vector<int> v2(10);
transform(v.begin().v.end().v2.begin(),bind(&point::x,_1));
}
該例中,transform()函數(shù)利用bind講變量v中的成員x全部填入到變量v2中泽疆。
4.綁定函數(shù)對象
什么是函數(shù)對象户矢?你不知道?函數(shù)對象其實是一個類的對象殉疼,只是因為這個類中重載了操作符梯浪,導(dǎo)致該對象調(diào)用這個操作符時,形式上看起來像個函數(shù)一樣瓢娜,其實它不是真的函數(shù)驱证,不要被誤導(dǎo)了喲。
首先來看一個函數(shù)對象的例子恋腕。
class FuncObjType
{
public:
void operator()()
{
cout<<"hello C++"<<endl;
}
}
當(dāng)bind綁定函數(shù)對象時抹锄,當(dāng)函數(shù)對象有內(nèi)部類型定義result_type,則bind可以自動推到出返回值類型荠藤,但如果函數(shù)對象沒用定義result_type伙单,則需要用模板參數(shù)指明返回類型:bind<result_type>(functor,...);
由于boost庫中大部分函數(shù)對象都有result_type,因此就可以直接使用bind哈肖,例如:
bind(std::greater<int>(),_1,10);
bind(std::plus<int>(),_1,_2);
bind(std::modulus<int>(),_1,3);
如果自定義函數(shù)對象吻育,沒有result_type的類型定義,就必須顯示地在模板參數(shù)中指明bind的返回值類型:
struct func
{
int operator()(int a,int b)
{
return a + b;
}
};
cout<<bind<int>(func::obj(),_1,_2)(10,20)<<endl;
文章參考:
用法講解:不破不立博客
工作機制探究:boost bind初步探究