ptr_fun/mem_fun/mem_fun_ref
背景介绍:当使用STL中的算法时,由于算法需要的回调函数既可以是普通函数也可以是仿函数,加入回调函数是普通函数,且算法对于函数的参数有一定要求,然而这个要求却限制了我们的需要,我们需要再另外在回调函数中加入参数时。
1、首先我们应当将普通函数转变为仿函数(函数对象)
2、在通过绑定适配器将仿函数的二元变为一元
因此将普通函数转变为仿函数的过程我们同样需要一种适配器即ptr_fun/mem_fun/mem_fun_ref三种
一、ptr_fun
将普通函数转变为仿函数
#include#include #include #include using namespace std; //取反适配器 //not2二元取反适配器 bool compare(int a,int b) { return a > b; }; void output(int a,int b) { cout << a+b << endl; }; void ori_output(int a) { cout << a << endl; }; int main() { vector<int> v; for (int i = 0; i < 5; i++) { v.push_back(rand() % 100); } sort(v.begin(), v.end(), ptr_fun(compare)); for_each(v.begin(), v.end(), ori_output); for_each(v.begin(), v.end(), bind2nd((ptr_fun(output)),2)); }
二、mem_fun_ref
如果使用普通函数作为回调函数存在一种问题,即函数无法使用与之有关的变量,而且通过设置全局变量的方式由不太妥当,因此我们使用普通的类内方法或者结构体中的方法作为回调函数。再将类内的方法或结构体中的方法转变为函数对象
类内方法转变为仿函数(一元)
class Func { public: Func(int a) { this->id = a; } public: int id; public: void print() { cout << id << endl; } }; int main() { vectorv; Func f1(1); v.push_back(f1); Func f2(2); v.push_back(f2); for_each(v.begin(), v.end(),mem_fun_ref(&Func::print)); return 0; }
类内方法转变为仿函数(二元)
class Func:public binary_function<int,int,void> { public: Func(int a) { this->id = a; } public: int id; public: void print(int x) const { cout << id + x << endl; } }; int main() { vectorv; Func f1(1); v.push_back(f1); Func f2(2); v.push_back(f2); //for_each(v.begin(), v.end(), mem_fun_ref(&Func::print)); for_each(v.begin(), v.end(), bind2nd(mem_fun_ref(&Func::print), 10)); return 0; }
注意:对于类内方法使用绑定适配器,该类需要继承binary_function的基类,继承时的模板申明同理,在上面的例子中模板申明为int,int,void原因是第一个参数为类内的公有成员,因此我们不用在方法的形参处写出,但是模板申明时必须进行申明
二、mem_fun
mem_fun与mem_fun_ref的功能一模一样,只不过使用mem_fun_ref的时候,容器内存放的是自定义的数据类型的指针。
int main() { vectorv; Func f1(1); v.push_back(&f1); Func f2(2); v.push_back(&f2); for_each(v.begin(), v.end(), mem_fun(&Func::print)); return 0; }