关于std::bind
关于 std::bind
std::bind C++ 11 的一个新函数,返回值为一个函数对象,可以看作一个通用的函数适配器。它接受一个函数作为参数,并返回一个新的函数同时将一至多个参数绑定到返回的函数中。下文的内容包括如何使用bind 以及什么时候使用bind。
如何使用
假如我们已经有一个函数:
int add(int a, int b){
return a + b;
}
bind
将一个函数作为它的第一个参数,并将这个函数的参数作为自己的参数。在下面的代码中,newAdd
以add
作为第一个参数,并且使用两个占位符来表示自己接受的参数。注意:_1, _2
表示占位符,位于<functional>
中,std::placeholders::_1
;另外,由于普通函数做实参时会隐式转换成函数指针,因此&add
可以用 add
替代。
using namespace std::placeholders;
auto newAdd = bind(&add, _1, _2);
在下面的代码中,5和6分别会与_1
,_2
绑定,被add()
调用。因此 newAdd(5,6)
等价于 add(5, 6)
cout << newAdd(5, 6) << endl; //11
我们也可以交换占位符,下面的代码中newAdd(5,6)
等价于 add(6,5)
:
auto newAdd = bind(&add, _2, _1);
int result = newAdd(5,6);
现在,假设我们需要用bind()
和 add()
写这样的一个函数:只接受一个整数 n,并且总是返回99+n
的结果,则我们可以这样写:
auto newAdd = bind(&add, 99, _1);
int result = newAdd(12); //111
在上面的代码中,_1
将会匹配到12,newAdd(12)
等价于add(99, 12)
。 注意下面的代码也能正常通过编译的:
int res2 = newAdd(1, 2, 3, 4, 5); //100
何时使用
由于 std::bind
返回的结果是一个函数对象,因此能很方便地使用在STL算法中。
假设现在我们有一个数组,我们需要统计数组中有多少个元素i
满足i%5==0
, 并且使用已有的函数divisible(int num, int den)
;
bool divisible(int num , int den){
if(num % den == 0)
return true;
return false;
}
若不使用bind()
我们可以这样写:
int main(){
vector<int> ary{ 1, 20, 13, 4, 5, 6, 10, 28, 19, 15 };
int count = 0;
for (int &i : ary){
if (divisible(i, 5)){
count++;
}
}
cout << count << endl; //4
return 0;
}
现在,我们使用bind()
和STL中的count_if()
:
//使用std::bind 和 counnt_if 解法
int main(){
vector<int> ary{ 1, 20, 13, 4, 5, 6, 10, 28, 19, 15 };
auto canDiv = bind(&divisible, _1, 5);
int count = count_if(ary.begin(), ary.end(), canDiv);
cout << count << endl; //4
return 0;
}
注意事项
std::bind
返回值的类型是一个函数对象,上面的代码中,我们只是使用auto
来直接接收bind() 类型的返回值。但是我们也可以用std::function
来接受返回的对象, 例如:
function<int(int, int)> newAdd = bind(&add, _1, _2);
推荐阅读
-
jQuery中绑定事件bind() on() live() one()的异同
-
jQuery的三种bind/One/Live/On事件绑定使用方法
-
关于mysql create routine 权限的一些说明
-
关于MySQL innodb_autoinc_lock_mode介绍
-
关于.NET动态代理的介绍和应用简介
-
javascript关于继承解析
-
解析android中的帮助、about、关于作者、HELP等提示页面
-
关于Android WebView的loadData方法的注意事项分析
-
Javascript:关于hasOwnProperty和IndexOf的性能对比
-
详解关于MySQL 8.0走过的坑