关于 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);

std::bind是C++11引入的一个功能,它允许将函数和参数预先绑定,创建一个新的可调用对象。本文介绍了如何使用std::bind,何时适合使用,以及使用时的注意事项。示例中展示了如何将函数与参数结合,以及在STL算法中的应用。
1万+

被折叠的 条评论
为什么被折叠?



