下面,我们再通过一个例子来说明。
现在,假设我们的需求是:获取一个集合中最小和最大值,并在稍后的时候(可能是另外一个函数中)打印它们。 这里,我们常规的做法通常是:通过一个函数获取集合的最大,最小值,然后保存住,最后在需要的时候访问这两个值,然后打印它们。
这样做就会需要解决:如果保存和传递最大,最小这两个值。
但实际上,这里我们可以考虑用闭包来实现这个功能,让闭包把最大,最小两个值捕获下来,然后在需要的地方调用就可以了。
请看一下下面这段代码:
void getMinMax(vector<int>& number, function<void ()>& printer) {
int min = number.front();
int max = number.front();
for (int i : number) {
if (i < min) {
min = i;
}
if (i > max) {
max = i;
}
}
printer = [=] () {
cout << "min:" <<min<< endl;
cout << "max:" << max << endl;
};
}
这里,我们通过function<void ()>& printer(如果你看不懂function,请看上文)传递出这个闭包。 然后,在需要的地方,这样即可:
function<void()> printer;
getMinMax(numbers, printer);
......
printer();
这里的printer其实是我们前面从getMinMax函数出传出的闭包,这个闭包捕获了min和max。我们直接传递这个闭包给需要的地方使用,而不用传递裸的两个数值,是不是优雅的不少?
std::bind
下面,我们再改进一下需求,假设我们要
打印出vector<int>中,20<x<40范围内的值 ,该怎么办?
毕竟,bool isBetween(int i, int min, int max) 这个函数可没法对应上
function<bool (int)> filter 啊!参数数量就不一样嘛。
这个时候,我们可以用 std::bind 。
std::bind的语法是这样的:
template <class Fn, class... Args> bind (Fn&& fn, Args&&... args);
template <class Ret, class Fn, class... Args> bind (Fn&& fn, Args&&... args);
std::bind可以将调用函数时的部分参数先指定好,留下一部分在真正调用的时候确定。
(当然,你也可以直接指定全部参数,在调用时不再指定。)
这里,isBetween中,最小,最大值其实我们是确定了的,即:20和40。而不确定的,其实是真正待判断的数字本身,那么我们就可以这么做:
std::bind(isBetween, placeholders::_1, 20, 40);
placeholders::_1 的意思是,这里是一个占位符,在调用的时候,将实际传递的第一个参数放到这里。
占位符的数量可以是任意多的,像这样:










