STL——前闭后开区间表示法和function call 操作符
前开后闭开区间表示法[)
任何一个STL算法,都需要获得由一对迭代器(泛型指针)所标示的区间,用以表示操作范围,这一对迭代器所标示的是个所谓的前闭后开区间,以[first,last)表示,也就是说,整个实际范围从first开始,直到last-1.迭代器last所指的是“最后一个元素的下一位置”。这种off by one(偏移一格,或说pass the end)的标示法,带来了很多方便,例如下面两个STL算法的循环设计,就显得干净利落:
- template<class InputIterator,class T>
- InputIterator find(InputIterator first,InputIterator last,const T&value)
- {
- while(first!=last&&*first!=value) ++first;
- return first; //返回迭代器
- }
- template <class InputIterator,class Function>
- Function for_each(InputIterator first,InputIterator last,Function f)
- {
- for(;first!=last;++first)
- f(*first);
- return f;
- }
前闭后开区间示意图如下(注意,元素之间无需占用连续内存空间):
function call 操作符
函数调用操作(C++语法中的左右小括号)也可以被重载。
许多STL算法都提供了两个版本,一个用于一般情况(例如排序时以递增方式排列),一个用于特殊情况(例如排序时由使用者指定以何种特殊关系进行排列),像这种情况,需要用户指定某个条件或某个策略,而条件或策略的背后由一整组操作构成,便需要某种特殊的东西来代表这“一整组操作”。
代表“一整组操作“的,当然是函数,过去C语言时代,欲将函数当做参数传递,唯有通过函数指针才能达成,例如:
- #include<iostream>
- #include<cstdlib>
- using namespace std;
- int fcmp(const void* elem1,const void* elem2);
- int main()
- {
- int ia[10]={32,92,67,58,10,4,25,52,59,54};
- for(int i=0;i<10;i++)
- cout<<ia[i]<<" ";
- cout<<endl;
- qsort(ia,sizeof(ia)/sizeof(int),sizeof(int),fcmp);
- for(int i=0;i<10;i++)
- cout<<ia[i]<<" ";
- cout<<endl;
- }
- int fcmp(const void* elem1,const void* elem2)
- {
- const int *i1=(const int*)elem1;
- const int *i2=(const int*)elem2;
- if(*i1<*i2)
- return -1;
- else if(*i1==*i2)
- return 0;
- else if(*i1>*i2)
- return 1;
- }
运行结果:
但是函数指针有缺点,最重要的是它无法持有自己的状态(所谓局部状态,local states),也无法达到组件技术中的可适配性(adaptability)——也就是无法再将某些修饰条件加诸于其上面而改变其状态。
- qsort函数:
- 功 能: 使用快速排序例程进行排序
- 头文件:stdlib.h
- 用 法: void qsort(void *base,int nelem,int width,int (*fcmp)(const void *,const void *));
- 参数: 待排序数组首地址
- 数组中待排序元素数量
- 各元素的占用空间大小
- 指向函数的指针,用于确定排序的顺序
为此,STL算法的特殊版本所接受的所谓“条件”或“策略”或“一整组操作”,都以仿函数形式呈现。所谓仿函数(functor)就是使用起来像函数一样的东西。如果你针对么某个class进行operator()重载,它就是一个仿函数,至于要成为一个可配接的仿函数,还需要做一些额外的努力。
- #include<iostream>
- //注意,不能使用using namespace std 不然plus和minus会有歧义
- using std::cout;
- using std::endl;
- template <class T>
- struct plus
- {
- T operator()(const T& x,const T& y) const {return x+y;}
- };
- template <class T>
- struct minus
- {
- T operator()(const T& x,const T& y)const {return x-y;}
- };
- int main()
- {
- plus<int> plusObj;
- minus<int> minusObj;
- cout<<plusObj(3,5)<<endl;
- cout<<minusObj(3,5)<<endl;
- //注意下面的调用,不要忘记调用默认构造函数的小括号以及函数对象调用参数的小括号
//以下直接产生仿函数的临时对象(第一对小括号),并调用之(第二对小括号)- cout<<plus<int>()(43,50)<<endl;
- cout<<minus<int>()(43,50)<<endl;
- }
运行结果:
STL——前闭后开区间表示法和function call 操作符的更多相关文章
- js 获取当前日期或者前、后N天yyyy-MM-dd的方法
//js获取当前日期.当前日期前.后N天的标准年月日 //day=0为当前天,day=7为前7天,day=-7为当前日期的后7天 function getstartdate(day) { ...
- JS计算前一天或后一天,前一月后一月
JS计算前一天或后一天,前一月后一月,上一天下一下,上一月下一月. 方法一: function ktkGetNextMonth(currentDate, scaleStep) { //scaleSte ...
- Effective STL 学习笔记 Item 21:Comparison Function 相关
Effective STL 学习笔记 Item 21:Comparison Function 相关 */--> div.org-src-container { font-size: 85%; f ...
- 腾讯云图片鉴黄集成到C# SQL Server 怎么在分页获取数据的同时获取到总记录数 sqlserver 操作数据表语句模板 .NET MVC后台发送post请求 百度api查询多个地址的经纬度的问题 try{}里有一个 return 语句,那么紧跟在这个 try 后的 finally {}里的 code 会 不会被执行,什么时候被执行,在 return 前还是后? js获取某个日期
腾讯云图片鉴黄集成到C# 官方文档:https://cloud.tencent.com/document/product/641/12422 请求官方API及签名的生成代码如下: public c ...
- js控制日期的前或后N天,前或后一个月
/*获取指定日期前或者后指定间隔时间* sdate:指定日期* interval:时间间隔* caret:间隔符*/function getNowFormatDate(sdate,interval,c ...
- 探究C语言中的前++和后++
小波带您探究c语言中的前++与后++: 欢迎吐槽,欢迎加QQ463431476. 欢迎关注! 现在来探究: 咱们先看第一个 i被赋值0,i++(后++)并没有输出1. 现在i被赋值0,++i,也 ...
- HMM 自学教程(七)前向后向算法
本系列文章摘自 52nlp(我爱自然语言处理: http://www.52nlp.cn/),原文链接在 HMM 学习最佳范例,这是针对 国外网站上一个 HMM 教程 的翻译,作者功底很深,翻译得很精彩 ...
- HMM 前向后向算法(转)
最近研究NLP颇感兴趣,但由于比较懒,所以只好找来网上别人的比较好的博客,备份一下,也方便自己以后方便查找(其实,一般是不会再回过头来看的,嘿嘿 -_-!!) 代码自己重新写了一遍,所以就不把原文代码 ...
- 隐马尔科夫模型HMM(二)前向后向算法评估观察序列概率
隐马尔科夫模型HMM(一)HMM模型 隐马尔科夫模型HMM(二)前向后向算法评估观察序列概率 隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数(TODO) 隐马尔科夫模型HMM(四)维特比算法 ...
随机推荐
- null和undefined的区别
不同之处: null是js语言的关键字,它表示一个特殊值,常用来描述“空值”.对null执行typeof运算,结果返回字符串“object”,也就是说,可以将null认为是一个特殊的对象值,含义是“非 ...
- __attribute__ ((section(".text")))的测试
一.测试原因 在学习u-boot的环境变量过程中,看到有如此的代码,现对涉及到的内容进行实验测试. 二.测试目的 1.了解gcc允许对段的属性进行更改的方法. 2.解决”ENV_IS_EMBEDDED ...
- 单例-b
这个比较老了,是mrc 里面的 此例以模仿Apple官方文档的单例写出来的.但是一直有一个非常不明白的地方,就是alloc与allocWithZone:的重载中,为什么要return [[self c ...
- 最好用的手机编程软件-C4droid
Q:c4droid是什么? A:c4droid(以下简称c4)是安卓平台上最强大的c/c++ 编译器,你可以在手机上用手机编写自己的C/C++程序,并且可以把程序导出成apk文件. 下载地址:http ...
- 转:SSDB:快速取代redis的nosql
原文来自于:http://hao.jobbole.com/ssdb%EF%BC%9A%E5%BF%AB%E9%80%9F%E5%8F%96%E4%BB%A3redis%E7%9A%84nosql/ S ...
- C++类型转换运算符
C++中提供4中类型转运算符,分别是:static_cast.dynamic_cast.reinterpret_cast和const_cast; 语法格式如下: 类型转换运算符 < type_i ...
- WPF开发技术介绍
本月做了一个小讲座,主要是WPF的开发技术介绍,由于是上班时间,去听的人不多,但对于自己来说至少是又巩固了Winform的知识,抽时间写一篇文章,在此分享给大家,有什么宝贵建议大家也可以提给我,谢谢. ...
- QMapControl介绍
QMapControl是Qt开发的基于LGPL协议开源的显示OpenStreetMap(下简称osm)Tile数据和基于wms-server服务的数据,这里做简单介绍并列出相关资源. QMapCont ...
- 给java中的System.getProperty添加新的key value对
由于系统被格了,所以,现在的java项目配置不对,代码里面的配置类调用了一个System.getProperty("env")发现找不到该变量的值,以前一直能找到的. 其实就是以前 ...
- mysql数据库操作语句大全
一 . 常用mysql命令行命令 1 .启动MYSQL服务 net start mysql 停止MYSQL服务 net stop mysql 2 . netstat –na | findstr 3 ...