bind是一组用于函数绑定的模板。在对某个函数进行绑定时,可以指定部分参数或全部参数,也可以不指定任何参数,还可以调整各个参数间的顺序。对于未指定的参数,可以使用占位符_1、_2、_3来表示。-1表示绑定后的函数的第1个参数,_2表示绑定后的函数的第2个参数,其他依次类推。
二:绑定成员函数
三:绑定成员变量
四:其他用法
假设有一个整数的向量,现在要获取其中大于20且小于30的个数:
2.特别注意点
bind可以绑定到普通函数、类的成员函数和类的成员变量。下面依次来讲解。
一:绑定到普通函数
首先我们定义一个函数my_divide,用来求得两个数的商。
#include<iostream>
#include<functional>
double my_divide(double x, double y)
{
return x / y;
}
int main()
{
using namespace std::placeholders; // adds visibility of _1, _2, _3,...
// binding functions:
auto fn_five = std::bind(my_divide, 10, 2); // returns 10/2
std::cout << fn_five() << '\n'; // 5
auto fn_half = std::bind(my_divide, _1, 2); // returns x/2
std::cout << fn_half(10) << '\n'; // 5
auto fn_invert = std::bind(my_divide, _2, _1); // returns y/x
std::cout << fn_invert(10, 2) << '\n'; // 0.2
auto fn_rounding = std::bind<int>(my_divide, _1, _2); // returns int(x/y)
std::cout << fn_rounding(10, 3) << '\n';
return 0;
}
二:绑定成员函数
#include<iostream>
#include<functional>
struct MyPair
{
double a, b;
double multiply() { return a*b; }
};
int main()
{
using namespace std::placeholders; // adds visibility of _1, _2, _3,...
MyPair ten_two = { 10,2 };
auto bound_member_fn = std::bind(&MyPair::multiply, _1); // returns x.multiply()
std::cout << bound_member_fn(ten_two) << '\n'; // 20
auto bound_member_data = std::bind(&MyPair::a, ten_two); // returns ten_two.a
std::cout << bound_member_data() << '\n'; // 10
return 0;
}
#include<iostream>
#include<string>
#include<functional>//std::bind
using namespace std;
class Base
{
public:
Base(int x = 0) :data(x) {}
void show(string name) { cout << name << endl; }
static int getNum() { return 10; }
int operator()(int i, int j, int k) { return i + j + k; }
private:
int data;
};
int main()
{
using namespace std::placeholders;
Base one(5);
//1.绑定类成员函数
auto show1 = bind(&Base::show, one, _1);
show1("123456"); //123456
auto show2 = bind(&Base::show, one, "123456");
show2(); //123456
//2.绑定静态成员函数
auto getnum = bind(&Base::getNum);
cout << getnum() << endl; //10
//3.绑定operator函数
auto oper = bind(&Base::operator(), one, _1, _2, 0);
cout << oper(1, 2) << endl; //3
auto oper1 = bind(Base(), _1, _2, 0);
cout << oper1(1, 2) << endl; //3
return 0;
}
#include<iostream>
#include<functional>//std::bind
using namespace std;
struct TAdd
{
int Add(int x, int y)
{
return x + y;
}
};
int main()
{
using namespace std::placeholders;
TAdd tAdd;
TAdd *p = new TAdd();
cout << bind(&TAdd::Add, tAdd, 2, 3)() << endl; //5
cout << bind(&TAdd::Add, p, 2, 3)() << endl; //5
return 0;
}
三:绑定成员变量
#include<iostream>
#include<functional>//std::bind
#include<map>
#include<string>
#include<algorithm>
using namespace std;
void Output(const string &name)
{
cout << name << endl;
}
int main()
{
using namespace std::placeholders;
map<int, string> m1;
m1.insert(pair<int, string>(1, "liuyi"));
m1.insert(pair<int, string>(2, "lisi"));
for_each(m1.begin(), m1.end(), bind(Output, bind(&map<int,string>::value_type::second, _1)));
return 0;
}
四:其他用法
1.嵌套绑定
假如要实现对一组向量进行排序:
#include<iostream>
#include<functional>//std::bind
#include<vector>
#include<algorithm>
using namespace std;
class CPerson
{
int age;
public:
CPerson(int _age=0):age(_age){}
int GetAge() { return age; }
};
int main()
{
using namespace std::placeholders;
vector<CPerson> vper;
vper.push_back(CPerson(2));
vper.push_back(CPerson(4));
vper.push_back(CPerson(1));
vper.push_back(CPerson(3));
sort(vper.begin(), vper.end(), bind(less<int>(), bind(&CPerson::GetAge, _1), bind(&CPerson::GetAge, _2)));
for_each(vper.begin(), vper.end(), [](CPerson x) {cout << x.GetAge() << endl; });
return 0;
}
假设有一个整数的向量,现在要获取其中大于20且小于30的个数:
#include<iostream>
#include<functional>//std::bind
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
using namespace std::placeholders;
vector<int> v;
v.push_back(10);
v.push_back(15);
v.push_back(21);
v.push_back(26);
v.push_back(31);
auto x = count_if(
v.begin(),
v.end(),
bind(logical_and<bool>(), bind(greater<int>(), _1, 20), bind(less<int>(), _2, 30))//same as " [](int a) {return (a > 20) && (a < 30); } "
);
cout << x << endl; //3
return 0;
}
2.特别注意点
bind中传值默认是值传递,当然可以改为引用传递
#include<iostream>
#include<functional>//std::bind
using namespace std;
void func(int &x)
{
x++;
}
int main()
{
using namespace std::placeholders;
//默认值传递
int n = 0;
bind(func, n)();
cout << n << endl; //0
//引用传递
bind(func, ref(n))();
cout << n << endl; //1
return 0;
}
参考自: http://www.cnblogs.com/hujian/archive/2012/12/08/2809298.html 和 http://www.cplusplus.com/reference/functional/bind/?kw=bind