STL学习笔记(仿函数)
仿函数(Functors)
仿函数(functor),就是使一个类的使用看上去象一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了。
例如我们定义一个类:
class X{public:return-value operator()(arguments) const;... };
然后就可以把这个类别的对象当做函数调用
X fo; ... fo(arg1,arg2) //等价于fo.operator()(arg1,arg2);
显然,这种定义形式更为复杂,却又三大妙处:
1.仿函数比一般函数更灵巧,因为它可以拥有状态。
2.每个仿函数都有其型别。因此可以将仿函数的型别当做template参数传递。
3.执行速度上,仿函数通常比函数指针更快。
仿函数可当做排序准则
1 #include <iostream> 2 #include <string> 3 #include <set> 4 #include <algorithm> 5 using namespace std; 6 7 class Person{ 8 public: 9 string firstname() const; 10 string lastname() const; 11 ... 12 }; 13 14 class PersonSortCriterion{ 15 public: 16 bool operator()(const Person&p1,const Person& p2) const { 17 return p1.lastname()<p2.lastname()|| 18 (!(p2.lastname()<p1.lastname())&& 19 p1.firstname()<p2.firstname()); 20 } 21 }; 22 23 int main() 24 { 25 typedef set<Person,PersonSortCriterion> PersonSet; 26 PersonSet coll; 27 PersonSet::iterator pos; 28 for(pos=coll.begin();pos!=coll.end();++pos){ 29 ... 30 } 31 ... 32 }
View Code
这里的coll适用了特殊排序准则PersonSortCritersion,而它是一个仿函数类别。所以可以当做set的template参数,而一般函数则无法做到这一点。
拥有内部状态的仿函数
下面例子展示仿函数如何模拟函数在同一时刻下拥有多个状态
1 #include <iostream> 2 #include <list> 3 #include <algorithm> 4 #include "print.cpp" 5 using namespace std; 6 7 class IntSequence 8 { 9 private: 10 int value; 11 public: 12 IntSequence(int initialValue):value(initialValue){} 13 int operator() () 14 { 15 return value++; 16 } 17 }; 18 19 int main() 20 { 21 list<int> coll; 22 generate_n(back_inserter(coll),9,IntSequence(1)); 23 PRINT_ELEMENTS(coll); 24 generate(++coll.begin(),--coll.end(),IntSequence(42)); 25 PRINT_ELEMENTS(coll); 26 }
View Code
for_each()的返回值
使用for_each()可以返回其仿函数。下面将演示这一点
1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 using namespace std; 5 6 class MeanValue 7 { 8 private: 9 long num; 10 long sum; 11 public: 12 MeanValue():num(0),sum(0){} 13 void operator() (int elem) 14 { 15 num++; 16 sum+=elem; 17 } 18 double value() 19 { 20 return static_cast<double>(sum)/static_cast<double>(num); 21 } 22 }; 23 24 int main() 25 { 26 vector<int> coll; 27 for(int i=1;i<=8;++i) 28 { 29 coll.push_back(i); 30 } 31 MeanValue mv=for_each(coll.begin(),coll.end(),MeanValue()); 32 cout<<"mean value:"<<mv.value()<<endl; 33 }
View Code
预定义的仿函数
C++标准程序库提供了许多预定义的仿函数。下面列出了所有这些仿函数
对对象排序或进行比较时,一般都以less<>为预设排序准则。要使用这些仿函数,必须包含头文件<functional>。
函数配接器(Function Adapters)
所谓“函数配接器”是指能够将仿函数和另一个仿函数(或某个值,或一般函数)结合起来的仿函数。函数配接器也声明与<functional>中。
例如以下语句:
find_if(coll.begin(),coll.end(),bind2nd(greater<int>()),42)
其中bind2nd是将一个二元仿函数(greater<>)转换成一元仿函数。它通常将第二参数传给“由第一参数指出”的二元仿函数,作为后者的第二参数。
下面列出了预定义的函数配接器
转载于:https://www.cnblogs.com/runnyu/p/4840489.html
STL学习笔记(仿函数)相关推荐
- C++ STL学习笔记
C++ STL学习笔记一 为何要学习STL: 数据结构与算法是编程的核心,STL中包含各种数据结构和优秀的算法,确实值得深入学习,本文中虽然着重使用,但希望有心的朋友能多看看相关数据结构的实现,对于C ...
- C++STL学习笔记(4) 分配器(Allocator)
在前面的博客<C++ STL学习笔记(3) 分配器Allocator,OOP, GP简单介绍>中,简单的介绍了分配器再STL的容器中所担当的角色,这一节对STL六大部件之一的分配器进行详细 ...
- C++ STL学习笔记(3) 分配器Allocator,OOP, GP简单介绍
继续学习侯捷老师的课程! 在前面的博客<C++ STL学习笔记(2) 容器结构与分类>中介绍了STL中常用到的容器以及他们的使用方法,在我们使用容器的时候,背后需要一个东西支持对内存的使用 ...
- C++ STL学习笔记 : 1. template 模板函数
本篇文章是学习C++ STL库的第一篇笔记,主要记录了使用template关键字创建模板函数的方法. 下面用一个非常简单的例子解释模板函数的用法 : #include <iostream> ...
- C++ STL学习笔记(2) 容器结构与分类
接着学习侯捷老师的C++ STL! 在使用容器的时候,需要明白容器中元素之间在内存里的关系是什么样的,是连续的,还是非连续的. 容器可以分为两类: 1. sequence container , 即序 ...
- C++ STL 学习笔记__(6)优先级队列priority_queue基本操作
10.2.7优先级队列priority_queue v 最大值优先级队列.最小值优先级队列 v 优先级队列适配器 STL priority_queue v 用来开发一些特殊的应用,请对stl的类 ...
- 【C++ STL学习笔记】C++ STL序列式容器(array,vector,deque,list)
文章目录 C++ STL容器是什么? 迭代器是什么,C++ STL迭代器(iterator)用法详解 迭代器类别 迭代器的定义方式 C++序列式容器(STL序列式容器)是什么 容器中常见的函数成员 C ...
- STL学习笔记(一)
2019独角兽企业重金招聘Python工程师标准>>> 1. 容器(Containers) 容器分为两类: 序列式容器(Sequence containers),此乃可序群集,其中每 ...
- SGI STL 学习笔记二 vector
sequence containers Array Vector Heap Priority_queue List sList(not in standard) Deque Stack Queue S ...
最新文章
- 设计模式 | 工厂方法模式及典型应用
- 打工人得努力了呀!AI虚拟人都要入职了…
- 使用Mysql数据库完成增删改查综合案例(JSP页面)
- mysql数据库的逻辑架构和存储引擎
- 特征提取——HOG方向梯直方图
- Word2Vec学习笔记(二)
- android keystore作用,如何使用Android KeyStore安全地存储任意字符串?
- 安装不上vc++环境,导致部分游戏和qq不能用的解决方案
- Linux 字符集问题
- linux 域名怎么平台,linux平台搭建DNS域名服务与常用配置
- Object强转为实体类类型失败!!!!!!
- tx2 ubuntu 修改屏幕分辨率
- 海康录像机识别不到硬盘_海康威视找不到硬盘
- 藏宝阁游戏服务器维护中,梦幻西游藏宝阁异常交易保护 | 手游网游页游攻略大全...
- 04-1下载Win系统(装机助理)
- 数字电路逻辑设计之逻辑函数
- 苹果电脑如何双开微信
- 嵌入式三级知识点整理
- 第十三章 音视频播放——Qt
- 系统的数据一致性到底是在说什么?我到今天才算真明白了
热门文章
- Android开发如何使用JNA
- Android卷一全文 第一章 阅读前的准备工作
- [react] 在React中如何引入图片?哪种方式更好?
- 前端学习(3180):ant-design介绍3
- 前端学习(3016):vue+element今日头条管理--总结
- [vue] 怎么解决vue打包后静态资源图片失效的问题?
- 工作107:静态路由
- 前端学习(2178):vue-router得参数传递二
- 前端学习(1764):前端调试值之性能分析的方法二
- “睡服”面试官系列第二十一篇之class基本语法(建议收藏学习)