std::placeholders::_1, std::placeholders::_2, …, std::placeholders::_N。
于是乎,对于 打印出vector<int>中,20<x<40范围内的值 这个需求,我们在不修改printNumber函数的基础上,通过定义一个isBetween函数:
bool isBetween( int i, int min, int max) {
return i >= min && i <= max;
}
然后,再这样就搞定了:
function<bool(int)> filter = std::bind(isBetween, placeholders::_1, 20, 40);
printNumber(numbers, filter);
当然,你甚至可以直接把这里的两行写成一行。
如果你不明白这段代码,请再看一下printNumber函数的定义:
void printNumber(vector<int>& number, function<bool (int)> filter) {
for (const int& i : number) {
if (filter(i)) {
cout<<i<<endl;
}
}
}
这里其实调用了filter(i)这个函数对象,而这个函数对象只接受一个int值作为参数,然后返回一个bool值。
function<bool(int)> filter = std::bind(isBetween, placeholders::_1, 20, 40);
绑定之后,只缺一个int型参数,所以正好对应得上。
如果不过瘾,我们再来看一个bind的例子。
我们常常需要在程序中,调用一些用户传过来的回调函数。而在回调函数中,用户常常会需要记录一些状态,于是常常希望通过一个对象的成员函数传给过来作为回调函数。但是在C++中,这样做是很麻烦的一个事情。因为,回调函数的类型我们很难定义。 但是,结合std::function和std::bind,一切变得容易多了。 结合前面的例子,现在就假设我们的回调函数是需要打印集合中的最大,最小值。
这里假设我们是通过一个类来记录和打印值的,这个类的定义是这样的:
class Printer {
private:
int min, max;
public:
Printer(int x, int y) {
min = x;
max = y;
}
void print() {
cout << "min:" << min << endl;
cout << "max:" << max << endl;
}
};
由于回调函数不需要参数,因此使用回调函数的代码是这样的:
void usingCallback(function<void ()> print) {
print();
}
然后,我们可以通过下面的方法来调用print函数
Printer printer = Printer(10, 50);
function<void ()> print = bind(&Printer::print, printer);
usingCallback(print);
成员函数其实是类中的方法绑定到一个对象上,然后执行调用。这里的代码很直观的表达了这个关系。
lambda表达式是如何实现的
lambda表达式是如何实现的呢?
其实是编译器为我们了创建了一个类,这个类重载了(),让我们可以像调用函数一样使用。所以,你写的lambda表达式和真正的实现,是这个样子的:










