本文共 1628 字,大约阅读时间需要 5 分钟。
仿函数(functors)是早期的命名,C++标准规格定案后采用的新名称是函数对象(function objects)(也就是一种具有函数特质的对象)。
仿函数的作用:
在C++的STL提供的各种算法,例如sort()。往往有两个版本,其中一个是最长用的某种运算的版本(operator<);第二个版本则表现出最泛化的演算流程,允许用户“以template参数来指定所需要采取的策略”。
仿函数产生的原因:
由于函数指针毕竟不能满足STL对抽象对象的需求,也不能满足软件积木的需求——函数指针无法和STL其它组件(如配接器adapter)搭配使用,产生更灵活的变化。
//仿函数1,比较大小template在上面的代码中,第一种调用方式是使用comp的定义的一个对象,然后通过这个对象来调用操作符(),来实现两个数组的比较的;对于第二个调用comp<int>()(1, 2)是产生一个临时(无名的)对象。struct comp{ bool operator()(T in1, T in2) const { return (in1>in2); }};comp m_comp_objext;cout << m_comp_objext(6, 3) << endl; //使用对象调用cout << comp ()(1, 2) << endl; //使用仿函数实现
在下面的使用场景(统计一个容器中的符合规定的元素),将说明之前提到的函数指针为什么不能在STL中替换掉仿函数
bool my_count(int num){ return (num < 5);}int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};std::vector v_a(a, a+10);cout << "count: " << std::count_if(v_a.begin(), v_a.end(), my_count);在上面我们传递进去了一个函数指针作为count_if的比较条件。但是现在根据新的需求,不再统计容器中小于5的变量个数,改为了8或者3。那么最直接的方法就是加一个参数threshold就可以了,就像下面这样
bool my_count(int num, int threshold){ return (num < threshold));}但是这样的写法STL中是不能使用的,而且当容器中的元素类型发生变化的时候就不能使用了,更要命的是不能使用模板函数。
那么,既然多传递传递参数不能使用,那就把需要传递进来的那个参数设置为全局的变量,那样确实能够实现当前情况下对阈值条件的修改,但是修改起来存在隐患(要是没有初始化就调用怎么办)。因而解决这样问题的方式就是仿函数
template这样的方式就很好的兼容了STL。struct my_count1{ my_count1(T a) { threshold = a; } T threshold; bool operator()(T num) { return (num < threshold); }};int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};std::vector v_a(a, a+10);cout << "count: " << std::count_if(v_a.begin(), v_a.end(), my_count1 (8));
转载地址:http://lfkhj.baihongyu.com/