关于std::bind

关于 std::bind

std::bind C++ 11 的一个新函数,返回值为一个函数对象,可以看作一个通用的函数适配器。它接受一个函数作为参数,并返回一个新的函数同时将一至多个参数绑定到返回的函数中。下文的内容包括如何使用bind 以及什么时候使用bind。

如何使用

假如我们已经有一个函数:

int add(int a, int b){
	return a + b;
}

bind将一个函数作为它的第一个参数,并将这个函数的参数作为自己的参数。在下面的代码中,newAddadd作为第一个参数,并且使用两个占位符来表示自己接受的参数。注意:_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);
发布了90 篇原创文章 · 获赞 31 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/BlackCarDriver/article/details/105452053