Effective STL 条款28

Effective C++ 第三版 所有条款总结及对应代码描述(纯干货) Effective C++ 第三版 所有条款总结及对应代码描述(纯干货) 阅读详情

条款28:了解如何通过reverse_iterator的base得到iterator

调用reverse_iterator的base成员函数可以产生“对应的”iterator,但这句话有些辞不达意。举个例子,看一下这段代码,我们首先把从数字1-5放进一个vector中,然后产生一个指向3的reverse_iterator,并且通过reverse_iterator的base初始化一个iterator:

vector<int> v;
v.reserve(5);     // 参见条款14
for(int i = 0;i < 5; ++ i) {   // 向vector插入1到5
 v.push_back(i);
 } 
vector<int>::reverse_iterator ri =   // 使ri指向3
 find(v.rbegin(), v.rend(), 3);
vector<int>::iterator i(ri.base());   // 使i和ri的base一样

执行上述代码后,可以想到产生的结果就像这样:

这张图很好,显示了reverse_iterator和它对应的base iterator之间特有的偏移量,就像rbegin()和rend()与相关的begin()和end()一样,但并没有说出了所有你需要知道的东西。特别是,它并没有解释怎样在ri上实现你在i上想要完成的操作。正如条款26解释的,有些容器的成员函数只接受iterator类型的参数,所以如果你想要在ri所指的位置插入一个新元素,你不能直接这么做,因为vector的insert函数不接受reverse_iterator。如果你想要删除ri所指位置上的元素也会有同样的问题。erase成员函数会拒绝reverse_iterator,坚持要求iterator。为了完成删除和一些形式的插入操作,你必须先通过base函数将reverse_iterator转换成iterator,然后用iterator来完成工作。

先让我们假设你要在ri指出的位置上把一个新元素插入v。特别的,我们假设你要插入的值是99。记住ri在上图中遍历的顺序是自右向左,而且插入操作会将新元素插入到ri位置,并且将原先ri位置的元素移到遍历过程的“下一个”位置,我们认为3应该出现在99的左侧。插入操作之后,v看起来像这样:

当然,我们不能用ri来指定插入的地方,因为它不是一个iterator。我们必须用i来代替。如上所述,当ri指向3时,i(就是ri.base())指向4。如果我们用ri来指定插入位置,那么用i指向插入位置,那个假设就是正确的。结论呢?

  • 要实现在一个reverse_iterator ri指出的位置上插入新元素,在ri.base()指向的位置插入就行了。对于insert操作而言,ri和ri.base()是等价的,而且ri.base()真的是ri对应的iterator。

现在再来考虑删除元素的情况。回顾一下最初的vector(也就是在插入99之前)ri与i的关系:

如果你要删除ri指向的元素,你不能直接使用i了,因为i与ri不是指向同一个元素。因此,你要删除的是i的前一个元素。

  • 要实现在一个reverse_iterator ri指出的位置上删除元素,就应该删除ri.base()的前一个元素。对于删除操作而言,ri和ri.base()并不等价,而且ri.base()不是ri对应的iterator。

我们还是有必要看看删除操作的代码,因为它还挺令人惊讶的。

vector<int> v;
...      // 向v插入1到5,同上
vecot<int>::reverse_iterator ri =
 find(v.rbegin(), v.rend(), 3);  // 同上,ri指向3
v.erase(--ri.base());    // 尝试删除ri.base()前面的元素;
      // 对于vector,一般来说编译不通过

这个设计并不存在什么问题。表达式--ri.base()确实能够指出我们需要删除的元素。而且,它们能够处理除了vector和string之外的其他所有容器。它可能也能处理vector和string,但对于大多数vector和string的实现,它无法通过编译。在这样的实现下,iterator(和const_iterator)会采用内建的指针来实现,所以ri.base()的结果是一个指针。

C和C++都规定了不能直接修改函数返回的指针,所以在string和vector的迭代器是指针的STL平台上,像--ri.base()这样的表达式无法通过编译。要移植从一个由reverse_iterator指出的位置删除元素时,你应该尽量避免修改base的返回值。没问题。如果你不能减少调用base的返回值,只需要先增加reverse_iterator的值,然后再调用base!

...      // 同上
v.erase((++ri).base());    // 删除ri指向的元素;
      // 这下编译没问题了!

因为这个方法适用于所有的标准容器,这是删除一个由reverse_iterator指出的元素时首选的技巧。

现在已经很清楚了,reverse_iterator的base成员函数返回一个“对应的”iterator的说法并不准确。对于插入操作而言,的确如此;但是对于删除操作,并非如此。当需要把reverse_iterator转换成iterator的时候,有一点非常重要的是你必须知道你准备怎么处理返回的iterator,因为只有这样你才能决定你得到的iterator是否是你需要的。

SAP 公司间库存调拨通过IDOC完成自动发票校验 本文仅用于SAP软件的应用与学习,不代表SAP公司。(注:文中所示截图来源SAP ERP软件,软件相应著作权归SAP所有。公司间采购时,通过SAP内部EDI 数据传输功能, 由销售方开的公司间发票自动触发采购方的发票校验。​欢迎扫码加如下微信,我会把大家拉到SAP PP学习群,随时欢迎跟我和其他SAP PP顾问一起交流和学习,如下图库存调拨订单,系统已经完成了发货方发货和收货方收货。 阅读详情

相关推荐

uniapp开发AndroidAPP集成支付宝支付及问题处理(商家订单参数异常等),集成微信小程序支付及问题处理(运行真机调试白屏)

2、选择支付宝支付,调用支付接口唤起支付宝支付。

qq_16785561的博客 3486

反向迭代器reverse_iterator与正向迭代器iterator之间的转换(以及实例应用)

反向迭代器     相信大家对正向迭代器应该都很熟悉,然而对于反向迭代器的使用确是有几处需要注意的地方,在此记录一下。先看STL源码处注释如下:   /** * Bidirectional and random access iterators have corresponding reverse * %iterator adaptors that iterate th...

weixin_40311211的博客 1万+

【文献阅读:信道估计】Deep Residual Learning Meets OFDM Channel Estimation

基于深度学习的信道估计技术

weixin_43178683的博客 1753

反向迭代器reverse_iterator与正向迭代器iterator之间的转换(list反向删除元素的方法)

首先,本文的公众号地址为:你真的会清理std::list的元素吗? 刚开通公众号,请求大家关注一下,谢谢大家。公众号二维码如下:有经验的程序员都知道,list是链表,可以遍历删除,删除的过程类似于以下代码(遍历删除521):int key=521;//程序员就不要爱情了吧 list::iterator it=l.begin();//l为std::list for (; it != l.en

onlysingleboy的专栏 8475

RDM协议控制端实战:从数据包构造到高效设备发现算法

本文深入探讨了RDM协议控制端的核心开发流程,涵盖从数据包构造、发送到响应解析的全过程。重点解析了如何利用二分搜寻算法高效实现网络设备发现,并分享了组包、解包中的关键代码实现与常见调试技巧,为舞台灯光与智能硬件领域的嵌入式开发提供实战指导。

week9的博客 457

Multisim14.0仿真实战:从零搭建RS/JK触发器电路(附真值表+波形图)

本文通过Multisim 14.0软件,提供了从零搭建RS触发器和JK触发器电路的详细仿真实战教程。内容涵盖核心概念解析、电路搭建步骤、动态波形观测及真值表分析,重点探讨了RS触发器的非法状态问题以及JK触发器的四种工作模式,帮助读者直观理解时序逻辑电路的“记忆”功能与设计要点。

weixin_29175469的博客 273

STL的反向迭代器

灵动阳光: http://www.sssit.org/blog/articles/233.html 反向迭代器reverse_iterator是一种反向遍历容器的迭代器,也就是从最后一个元素到第一个元素遍历容器。反向迭代器的自增(或自减)的含义反过来了:对于反向迭代器,++运算符将访问前一个元素,–运算符将访问下一个元素。 在某些场景下,reverse_it...

weixin_30593443的博客 252

Qt 插件开发 plugin 超详细 有源码

Qt 插件化开发框架类似于前后端的微服务的场景,授权哪个微服务则前端可以使用哪个微服务,插件就行硬件插卡一样,可以被随时删除、插入和修改,所以结构很灵活,容易修改,方便软件的升级和维护;插件主要面向接口编程,无需访问.lib文件,热插拔、利于团队开发。即使在程序运行时.dll不存在,也可以正常启动,只是相应插件功能无法正常使用而已;动态库需要访问.lib文件,而且在程序运行时必须保证.lib存在,否则无法正常启动;

q610098308的专栏 6544

【C++】迭代器、反向迭代器详解

http://c.biancheng.net/view/338.html https://blog.youkuaiyun.com/kjing/article/details/6936325 https://blog.youkuaiyun.com/qq_22194315/article/details/57144854 一、迭代器 1. 概述 要访问顺序容器和关联容器中的元素,需要通过“迭代器(iterator)”进行。迭代器是一个变量,相当于容器和操纵容器的算法之间的中介。迭代器可以指向容器中的某个元素,通过迭代器就可以读..

lemonxiaoxiao的博客 6037

bartender 10.1破解版|bartender条码打印10.1

点击下载出处:BarTender10.1破解版 bartender10.1破解版是一款专业的条码打印软件,在行业内广受好评,通过使用bartender我们可以将标签设计这个复杂的过程变得更简便,在设计中快速调整,即刻打印,非常迅速,BarTender10.1破解版不仅支持的标签类型包括EPC Class 1 、Gen2 、ISO 18000-6b 、ISO 15693 、Tag-It 、I-CO...

weixin_44924147的博客 6万+

使用MATLAB/Simulink对一个简单的智能家居温湿度监测与控制系统进行建模和仿真

目录手把手教你学Simulink——基于Simulink的智能家居温湿度监测与控制仿真建模示例一、背景介绍二、所需工具和环境三、步骤详解步骤1:创建Simulink模型步骤2:构建传感器模块步骤3:添加控制器步骤4:构建执行器模块步骤5:连接各部分步骤6:设置仿真参数步骤7:添加观测器步骤8:运行仿真并分析结果四、总结 智能家居系统中的温湿度监测与控制系统是一个典型的物联网(IoT)应用场景,它通过传感器收集环境数据,并根据预设条件自动调节室内温度和湿度以提高居住舒适度。本指南将介绍如何使用MATLAB/S

xiaoheshang_123的博客 291

effective STL 条款27 和 条款28

#include #include #include #include using namespace std; int main() { //条款27:用distance和advance把const_iterator转化成iterator typedef deque IntDeque; typedef IntDeque::iterator Iter; typedef IntD

wangwenwen的专栏 1019

Qt/C++编写自定义控件42-开关按钮

一、前言 从2010年进入互联网+智能手机时代以来,各种各样的APP大行其道,手机上面的APP有很多流行的元素,开关按钮个人非常喜欢,手机QQ、360卫士、金山毒霸等,都有很多开关控制一些操作,在Qt widgets应用项目上,在项目中应用些类似的开关按钮,估计也会为项目增添不少新鲜感。 总结了大部分的开关按钮控件,基本上有两大类,第一类是纯代码绘制,这种对代码的掌控度要求比较高,但是灵活性比较好...

Qt/C++视频监控/推流/物联网/大屏系统/自定义控件/UI定制/输入法 3327

《effective stl》条款28:了解如何通过reverse_iterator的base得到iterator

出处:http://blog.163.com/suyangcs@126/blog/static/11328019320131019112736744/ 例: vector v; vector::reverse_iterator ri =  find(v.rbegin(), v.rend(), 3);    // 使ri指

jiaoyongqing134的专栏 385

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Effective STL 条款29

条款29:需要一个一个字符输入时考虑使用istreambuf_iterator 假设我们要把一个文本文件拷贝到一个字符串对象中。似乎可以用一种很有道理的方法完成: ifstream inputFile("interestingData.txt");string fileData((istream_iterator(inputFile)), // 把inputFile读入

AMin2001的专栏 1713

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

读书笔记《Effective C++》条款28:避免返回handles指向对象内部成分

先看个例子。

Do-Program的专栏 393

effective stl 第28条:正确理解由reverse_iterator的base()成员函数所长生的iterator的用法

vector<int> v; v.reserve(5);//保留5个大小的容量 for (int i = 1; i <= 5; i++) { v.push_back(i); } vector<int>::reverse_iterator ri = find(v.rbegin(), v.rend(), 3);//找到3的位置 vector

sun%moon 425

Effective STL 条款35

条款35:通过mismatch或lexicographical比较实现简单的大小写无关字符串比较一个STL菜鸟最常问的问题是“我怎么使用STL来进行大小写无关的字符串比较?”这是一个令人迷惑的简单问题。大小写无关字符串比较要么真的简单要么真的困难,依赖于你要多一般地解决这个问题。如果你忽略国际化问题而且只关注于设计成字符串strcmp那样的类型,这个任务很简单。如果你要有strcmp不具有

AMin2001的专栏 1859

Effective STL 条款3

条款3:使容器里对象的拷贝操作轻量而正确 容器容纳了对象,但不是你给它们的那个对象。此外,当你从容器中获取一个对象时,你所得到的对象不是容器里的那个对象。取而代之的是,当你向容器中添加一个对象(比如通过insert或push_back等),进入容器的是你指定的对象的拷贝。当你从容器中获取一个对象时(比如通过front或back),你取到的是容器中那个对象的拷贝。拷进去,拷出来。这就是STL的方

AMin2001的专栏 1680

Effective STL 条款39

条款39:用纯函数做判断式我讨厌为你做这些,但我们必须从一个简短的词汇课开始: 判断式(predicate)是返回bool(或者其他可以隐式转化为bool的东西)。判断式在STL中广泛使用。标准关联容器的比较函数是判断式,判断式函数常常作为参数传递给算法,比如find_if和多种排序算法。(排序算法的概览可以在条款31找到。) 纯函数是返回值只依赖于参数的函数。如果f是一个纯

AMin2001的专栏 1965

Effective STL 条款38

条款38:把仿函数类设计为用于值传递C和C++都不允许你真的把函数作为参数传递给其他函数。取而代之的是,你必须传指针给函数。比如,这里有一个标准库函数qsort的声明:void qsort(void *base, size_t nmemb, size_t size, int (*cmpfcn)(const void*, const void*));条款46解释了为什么sort

AMin2001的专栏 1702

Effective STL 条款30

条款30:确保目标区间足够大STL容器在被添加时(通过insert、push_front、push_back等)自动扩展它们自己来容纳新对象。这工作的很好,有些程序员因为这个信仰而被麻痹,认为他们不必担心要为容器中的对象腾出空间,因为容器自己可以照顾好这些。如果是那样就好了!当程序员想向容器中插入对象但并没有告诉STL他们所想的时,问题出现了。这是一个常见的可以自我表现的方法:int

AMin2001的专栏 1762

Effective STL 中文版(大全)

候捷说,对于STL,程序员有三个境界,开始是使用STL,然后是理解STL,最后是补充STL。EffectiveSTL是一本非常好的书,帮助你更好的理解STL,其作者就是《EffectiveC++》一书的作者。如果你已经初步了解了STL的容器、迭代器、算法和函数,而又想更好的了解STL,那么《EffectiveSTL》是你的最佳选择。 还有一部分没有找到链接,如果再找不到我会自己试着翻译

幸福村的人 1139

Effective STL 条款18

Item18避免使用vector 做为一个STL容器,vector有两个问题.第一,它不是一个真正STL容器,第二,它并不保存bool类型.除此以外,并没有太多东西与本节题目有关(译注,还不够多吗)一个东西不能成为一个STL容器,只因为会有人说它是一个(译注,:( ).一个东西要成为STL容器,必须满足所有列于C++标准23.1节的容器要求.在这些要求中,有这样一条:如果C是一个T类型元素容器

solotony的专栏 1674

Effective STL 条款2

条款 2: 小心对“容器无关代码”的幻想STL是建立在泛型之上的。数组泛化为容器,参数化了所包含的对象的类型。函数泛化为算法,参数化了所用的迭代器的类型。指针泛化为迭代器,参数化了所指向的对象的类型。这只是个开始。独立的容器类型泛化为序列或关联容器,而且类似的容器拥有类似的功能。标准的内存相邻容器(参见条款1)都提供随机访问迭代器,标准的基于节点的容器(再参见条款1)都提供双向迭代器。序列

AMin2001的专栏 1651

Effective STL条款50

条款50:让你自己熟悉有关STL的网站因特网充满了STL的信息。用你最喜欢的搜索引擎寻找“STL”,它一定会返回几百个链接,其中有一些可能实际上是相关的。不过,对于大多数STL程序员,没有必要搜寻。下列网站应该要提升到几乎每个人的最常使用列表的顶端: SGI STL网站,http://www.sgi.com/tech/stl/。 STLport网站,http://www.stlpo

AMin2001的专栏 2776
上一篇: Effective STL 条款13
下一篇: Effective STL 条款35
AMin2001
博客等级 码龄26年 7粉丝 35原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值