C++STL 仿函数 小灰灰 2022-06-13 21:09 127阅读 0赞 ## ## ## 1. 概述 ## 仿函数(functors)是早期的命名,C++标准规格定案后采用的新名称是函数对象(function objects)(也就是一种具有函数特质的对象)。 **仿函数的作用**: 在C++的STL提供的各种算法,例如sort()。往往有两个版本,其中一个是最长用的某种运算的版本(operator<);第二个版本则表现出最泛化的演算流程,允许用户“以template参数来指定所需要采取的策略”。 **仿函数产生的原因**: 由于函数指针毕竟不能满足STL对抽象对象的需求,也不能满足软件积木的需求——函数指针无法和STL其它组件(如配接器adapter)搭配使用,产生更灵活的变化。 ## 2. 编码 ## ### 2.1 仿函数实现示例 ### //仿函数1,比较大小 template<typename T> struct comp { bool operator()(T in1, T in2) const { return (in1>in2); } }; comp<int> m_comp_objext; cout << m_comp_objext(6, 3) << endl; //使用对象调用 cout << comp<int>()(1, 2) << endl; //使用仿函数实现 在上面的代码中,第一种调用方式是使用comp的定义的一个对象,然后通过这个对象来调用操作符(),来实现两个数组的比较的;对于第二个调用comp<int>()(1, 2)是**产生一个临时(无名的)对象**。 ### 2.2 仿函数详细说明 ### 在下面的使用场景(统计一个容器中的符合规定的元素),将说明之前提到的函数指针为什么不能在STL中替换掉仿函数 bool my_count(int num) { return (num < 5); } int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; std::vector<int> 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<typename T> 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<int> v_a(a, a+10); cout << "count: " << std::count_if(v_a.begin(), v_a.end(), my_count1<int>(8)); 这样的方式就很好的兼容了STL。
还没有评论,来说两句吧...