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(四)维特比算法 ...
随机推荐
- 算法系列之图--BFS
广度优先搜索以源结点s为出发点,算法始终将已发现和未发现结点之间的边界,沿其广度方向向外扩展.也即算法需要在发现所有距离源结点s为k的所有结点之后才会去发现距离源结点距离为k+1的其他结点. talk ...
- 织梦 dedecms 中LOOP 万能标签循环 调用 arcurl标签(获取链接)
在DEDECMS中,提供了loop万能循环标签,但是此循环标签只能循环出该表中的字段,而“[field:arcurl/]”链接标签并不能被解析出来,而DEDECMS官方论坛上也没有找到相关的解决办法, ...
- tableview 重用nib cell
#import "ViewController.h" #import "NewsTableViewCell.h" #define UISCREEN_HEIGHT ...
- UNIX Filesystems - Evolution Design and Implementation.pdf
UNIX Filesystems - Evolution Design and Implementation.pdf
- hibernate spring sturts2配置
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hi ...
- BZOJ 1007 水平可见直线
Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则Li为被覆盖的. 例如,对于直线: ...
- google yeoman
Yeoman是Google的团队和外部贡献者团队合作开发的,他的目标是通过Grunt(一个用于开发任务自动化的命令行工具)和Bower(一个HTML.CSS.Javascript和图片等前端资源的包管 ...
- javascript widget ui mvc
MVC只是javascript的一个UI模式 JavaScript UI----UI, Template, MVC(View)----Backbone, Angular RequireJS------ ...
- 如何给div加一个边框border样式
如何给div加一个边框样式? 对div盒子加一个边框样式很简单只需要使用border板块样式即可. 一.虚线与实线边框 边框虚线样式:dashed 边框实现样式:solid border:1px da ...
- 快学Scala第一部分
转载: 1.变量声明 val answer = 8 * 5 + 2; //常量 var counter = 0; //变量 //在必要的时候 ,可以指定类型 val greeting:Strin ...