谈一谈stl的iterator

条款13:优先选用const_iterator,而非iterator 摘要:优先选用const_iterator的实践指南 在STL中,const_iterator(指向不可修改元素的迭代器)比普通iterator更安全、更清晰地表达“只读”意图。C++98中由于支持不足(创建困难、使用受限),其优势难以发挥;但C++11通过cbegin()/cend()等成员函数和非成员函数std::begin()显著改善了可用性。 核心建议: 默认使用const_iterator:除非需要修改元素,否则优先选择它以避免意外修改,增强代码安全性。 C++11/14优化:利用非成员函数(如s 阅读详情

这两天,使用std::map的iterator的时候,遇到了很多的问题,最后发现很多想当然的想法是错误的。
比如:list的iterator自减到了begin()之后,再自减的话会回到end(),从而形成一个循环队列。
而map的iterator如果一直自减到begin()之后,继续自减的话,iterator会始终指向begin();end()之后自增的话,也不会有任何改变。
其实上述行为还与stl的实现有关,比如stlport的map,end()之后自增,iterator不会始终指向end()。所以我们可以只能认为iterator在begin()之后--、或者end()之后++,这两种行为的效果是未定义的,使用的时候必须非常小心。

以下,针对vc和stlport的stl实现,就各种容器的iterator作一个总结:
1. list: vc和stlport的实现是一致的,即循环队列。begin()-- = end(),end()++ = begin()。list::iterator实际上存储的是指向元素的指针。
2. vector: 在vc和stlport中,vector都使用整数作为iterator,所以begin()--,end()++如果反引用的话都是对内存的违规访问。
3. map/set: map和set本质上都是使用一个treebase的结构。实际上set就是只有key的map。如前所述vc中begin()--,以及end()++都不会有任何操作。但是stlport中确对end()++有特殊处理(注意以下代码中的check special case),由于暂时还没没有研究map中使用的树的操作方式(这得复习数据结构的知识了,以后有空再说吧),所以对下面这段代码的意思还没搞清楚。不过从效果上来看,end()++是变化的。

template <class _Dummy> _Rb_tree_node_base* _STLP_CALL
_Rb_global<_Dummy>::_M_increment(_Rb_tree_node_base* _M_node) {
  if (_M_node->_M_right != 0) {
    _M_node = _Rb_tree_node_base::_S_minimum(_M_node->_M_right);
  }
  else {
    _Base_ptr __y = _M_node->_M_parent;
    while (_M_node == __y->_M_right) {
      _M_node = __y;
      __y = __y->_M_parent;
    }
    // check special case: This is necessary if _M_node is the
    // _M_head and the tree contains only a single node __y. In
    // that case parent, left and right all point to __y!
    if (_M_node->_M_right != __y)
      _M_node = __y;
  }
  return _M_node;
}

总结一下:做任何事情,动手之前都必须深思熟虑。对于可能存在错误的地方,必须检查清楚,否则等到代码写完之后再回头来检查,那将是非常困难的事情。
这两天使用map时,写代码的时候已经意识到iterator的begin()--和end()++可能有问题,但是当时由于急于求成,没有停下来好好研究一下iterator,而是想着等出了问题再回头来研究(这时实际上抱着一种侥幸心理,如果没出问题的话,那就不用花时间研究iterator了)。结果果然出了问题,而出了问题的时候早已把begin()--和end()++忘掉了,这时候必须通过设断点,单步运行等手段一步一步检查可能出现的错误,花了半天才想起begin()--的问题。由此看来做事千万不要有侥幸心理,否则因小失大、得不偿失!

C++STL为什么要有const_iterator const_iterator的一系列问题。 阅读详情

相关推荐

STL: reverse_iterator / iterator 关系以及 erase 相关(C++)

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

zhangpiu的专栏 1232

C++迭代器

迭代器简介除了使用下标来访问 vector 对象的元素外,标准库还提供了另一种访问元素的方法:使用迭代器(iterator)。迭代器是一种检查容器内元素并遍历元素的数据类型。标准库为每一种标准容器(包括 vector)定义了一种迭代器类型。迭代器类型提供了比下标操作更通用化的方法:所有的标准库容器都定义了相应的迭代器类型,而只有少数的容器支持下标操作。因为迭代器对所有的容器都适用,现代 C++ 程序更倾向于使用迭代器而不是下标操作访问容器元素,即使对支持下标操作的 vector 类型也是这样。容器的iter

低调走过 1737

C++ STL源码剖析之实现一个简单的iterator_category

C++ STL源码剖析之实现一个简单的iterator_category导语利用萃取机实现一个简单的iterator_category识别STL源码剖析Iterator 导语 本节使用上节Traits特性,研究iterator源码,来实现一个简单的iterator_category,同时对iterator的源码结构进行分析。 知其然,知其所以然,源码面前了无秘密! 利用萃取机实现一个简单的iterator_category识别 迭代器是指向序列元素的指针的一种抽象。通过使用迭代器,我们可以访问序列中的某个元

希望我的博客,能帮上你解决学习中工作中所遇到的问题 733

C++——迭代器简介

第一篇C++的知识介绍......简单的介绍了一下迭代器的概念和用法

Cipher的博客 1100

手把手教你用Trae配置Python开发环境(含Claude 3.5代码生成实战)

本文详细介绍了如何使用字节跳动推出的Trae智能开发环境配置Python开发环境,并实战演示了Claude 3.5代码生成功能。从环境准备到项目初始化,再到AI辅助编码和调试优化,全面展示了Trae在提升开发效率方面的强大能力,特别适合Python开发者快速搭建项目和解决复杂问题。

weixin_28309571的博客 976

免费获取船舶轨迹数据?手把手教你用Python处理中国海洋卫星AIS数据

本文详细介绍了如何免费获取中国海洋卫星AIS数据,并使用Python进行船舶轨迹数据的处理与分析。从数据源评估到自动化处理流水线,再到高级分析与可视化技巧,手把手教你避开常见问题,实现高效数据处理。特别适合航运数据分析、物流优化和海上安全研究等领域的研究者和开发者。

weixin_42616115的博客 320

STL中end()和rbegin()的区别

反向迭代器是一种反向遍历容器的迭代器。也就是从最后一个元素到第一个元素的遍历容器,所以自然地反向迭代器将自增(自减)的含义反过来了,++运算将访问前一个元素,--运算则访问下一个元素。 在使用STL时,经常需要用到迭代器,多以一定要搞清楚一些指针的区别。其中begin()指向第一个元素,但是end()不是指向最后一个元素,而是最后一个元素的后一个元素。所以在使用unordered_...

Liar_27的博客 2976

SAP 关于WPS上传文件提示“文档中不包含数据“ 和“程序正在运行中“处理办法

最近这一周经常有用户反馈,使用WPS上传文件系统报错,一直提示“程序正在运行中”,另外在导入数据的时候提示"文档中不包含数据",跟进运维过程中遇到的这两种情况,分享一下处理的办法,如果各位更好的办法也可以给我留言分享。

我小时候很黑的博客 2845

C++中STL库中begin()和end()

c.begin(); 返回指向容器最开始位置数据的指针 c.end(); 返回指向容器最后一个数据单元+1的指针 如果要输出最后一个元素的值应该是 *(–c.end()) 两个代码片段: #include <bits/stdc++.h> using namespace std; int main() { set <int> s; s.insert(5); s.insert(7); s.insert(2); s.insert(1);

heros_123456的博客 2007

数字逻辑设计大程——以撒的结合(Verilog语言)

前言 在大二学习数字逻辑设计课程(即计算机组成课程的前引课)时,期末大程题目我和同组的github成员lwaekfjlk 决定写一款基于Verilog语言的游戏。原型是我们两人都非常喜爱的一款游戏——The Binding of Isaac: Rebirth。在三天三夜的奋战后,基本完成了预期目标。由于亲自编写了其中种种,我们深知新手初期使用Verilog语言有多困难。而可悲的是,这又是之后计算机组成课程和体系结构课程所需的!因此,我们将top部分源码放在这里,供同袍们参考。若想引用还请注明出处。 代码部分

LuvLucifer的博客 1383

对CryptoDriver里密钥格式定义的探索(1)

一入网络安全才发现深似海,传统汽车MCU码农转型之路异常艰难。在CP AUTOSAR中的CryptoDriver SWS对密钥格式的需求来源于RFC,其中要求了RSA、ECC、SHE等key material的格式。再往下看,我就有些迷糊了,例如关于RSA Private Key的OCTEE STRING格式根据IETF RFC8017,Public Key又得根据RFC5280,完全不得其解。所以今天先从生成密钥对,并对其进行解析开始,一步一步拆解。

认真搞搞汽车MCU 527

C++ 迭代器 iterator 详解

迭代器 功能:访问容器对象的元素。所有标准库容器都可以使用迭代器,其中只有少数几种才同时支持下标运算符。严格来说,string对象不属于容器类型,但是string支持很多与容器类型类似的操作。迭代器分为有效和无效,类似于指针。有效的迭代器:指向某个元素,或者指向容器中尾元素的下一个位置;无效的迭代器:除上述的其他所有情况。

WWester的博客 2605

你分得清ChatGPT、Gemini、Grok、豆包、千问、DeepSeek、OpenClaw、CloudCode、vibeCodeing、sKill、MCP,飞书、微信这些到底是什么吗?

AI技术生态呈现层级化发展,从基础模型到应用平台形成完整技术栈。核心分为五层:模型层(GPT、Gemini等基础模型)→AI助手层(ChatGPT等应用产品)→工具层(ClaudeCode等开发工具)→协议层(MCP等接口标准)→应用层(微信、飞书等平台)。未来趋势将形成"模型公司-开发框架-应用生态"三层结构,AI正逐步演变为新型操作系统,通过标准化协议连接各类外部系统,实现能力调用与生态整合。技术发展呈现出从底层基础设施到上层应用场景的垂直整合特征。

hy行者勇哥的博客 396

STL iterator 基本原则

STL iterator 基本原则   有效使用STL迭代器的三条基本原则 STL迭代器的概念看上去似乎已经足够直观了,然而,你会很快发现容器类(Container)实际上提供了四种不同的迭代器类型:iterator、const_iterator、reverse_iterator和const_reverse_iterator。进而,你会注意到容器类的insert和erase方法仅接受这四种

3603

基于DNN神经网络的多输入多输出数据回归预测(附带Matlab代码)

假设我们的输入数据包含n个特征,输出数据包含m个特征。在本文中,我们将介绍如何使用DNN(深度神经网络)实现多输入多输出数据回归预测,并提供相应的Matlab代码。需要注意的是,上述代码中的DNN模型是一个简化的示例,您可以根据实际任务的复杂程度和要求进行相应的调整和优化。综上所述,我们介绍了如何使用DNN神经网络实现多输入多输出数据回归预测,并提供了相应的Matlab代码。函数对DNN模型进行训练,其中输入数据需要转置,以适应网络的输入要求。最后,我们使用训练好的模型对测试数据进行预测,并打印预测结果。

DevWizard的博客 1067

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

STL 简单 iterator adapters 的实现

1. 简介 配接器(adapters)在STL组件的灵活组合上,扮演者轴承、转换的角色。Adapters事实上是一种设计模式(design pattern)。 百度百科对adapters模式的解释: 将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。——Gang of Four          在STL的体系中,有

chengonghao的博客 1850

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

stl源码剖析笔记之iterator

此系列是本人阅读《STL源码剖析》的一点心得体会,并结合部分STL源码加深理解。此篇博客为第三章iterator的读书笔记。 综述     有个地方容易混淆,首先,有五种iiterator input iterator output iterator forward iterator, bidirectional iterator, random-access iterator

朱明代月的博客 854

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

STL下的iterator traits

文章目录前言迭代器相应型别(associated types)模板特化value_typedifference_typereferencepointeriterator_categoryadvanced()为例为什么代表迭代器类型的class使用继承std::iterator 的保证完整代码重列 前言 迭代器就是所谓泛型指针,《Design Patterns》一书中将迭代器定义为:提供一种方法,使之能依序遍历某个聚合物(容器)所含的各个元素,而又无需暴露该聚合物的内部表述方式。面向对象设计推崇将算法封装.

qq_53558968的博客 672

C++STL Iterator和traits

STL Iterator和traits STLIterator 1.Iterator定义 STL的中心思想在于将数据容器和算法分开,彼此独立设计,然后再用一个粘合剂将其黏再一起,这个粘合剂就是iterator。 迭代器是一种智能指针,它针对指针中最常见的内容提领(dereference)和成员访问(member access),这里隐含的一个重要的消息就是迭代器必须包含原生指针,即接待器是原生指针的一种拓展。所以迭代器最重要的就是重载operator*和operator->。 2.实现.

b711183612的专栏 1092

C++ STL源码分析——iterator分类

【侯捷-SL体系结构内核分析-iterator】 itertor需要向algorithm提供自身的类型 iterator_category,iterator分为以下五种类型: random_access_iterator_tag,可跨任意距离取值 bidirectional_iterator_tag,可前进或后退 forward_iterator_tag input_iterator_tag o...

ZLP_优快云的博客 581

STL(二):Iterator

前言 如果把STL的algorithm包含了各种算法的实现,这些算法必须能对不同的容器和容器的适配器进行操作,比如下面的例子: #include <bits/stdc++.h> using namespace std; int main(){ vector<int> m_vec{1, 3, 2, 4}; deque<int> m_deque{1, 3, 2, 4}; sort(m_vec.begin(), m_vec.end()); so

csy777777的博客 295

STL源码剖析:Iterator

迭代器不一定是class,它有可能是native pointer,原生指针无法定义其关联类型,所以需要一个萃取机来分辨所得到的iterator是class还是native pointer,并利用partial specialization(偏特化)来得到其关联的类型。对于外部接口,只接受迭代器和相关参数。对于没有指定类型对应的重载函数时,会调用参数类型为其父类的重载函数。input_iterator_tag: 该种迭代器所指向类型只读。output_iterator_tag: 所指向类型只写。

m0_61722509的博客 734

C++ STL const_iterator转换为iterator类型迭代器(深入了解,一文学会)

在 advance() 和 distance() 函数各自的功能和用法基础上,继续讲解如何利用这 2 个函数实现将 const_iterator 迭代器转换为 iterator 迭代器,或者将 const_reverse_iterator 迭代器转换为 reverse_iterator 迭代器。 注意,上面提到的 iterator、const_iterator、reverse_iterator 和 const_reverse_iterator 是 C++ STL 标准库提供了 4 种基础迭...

断点 1943

C++ STL:迭代器特性 iterator_traits

STL的算法需要知道iterator的相关信息(iterator种类、iterator指向的元素的类型...),来决定使用最优化的算法。然而,原生指针本身并不是一个类类型,它们没有定义,但是标准库中泛型算法和容器希望迭代器都有上面提到的5种特性,但是对于原生指针,并没有任何结构定义。支持前面四种Iterator的所有操作,并另外支持it + n、it - n、it += n、 it -= n、it1 - it2和it[n]等操作。不同类型的迭代器支持的操作不同,在算法优化的时候需要用到。

_ 1361

STL Iterator 迭代器全揭秘

Iterator 是 STL 的基础,STL 算法都是基于 iterator。本文基于 gcc-12.2 分析了迭代器实现。

谢谢大家的关注 634
上一篇: 几个小知识点
下一篇: 最近工作中犯的一些错误,以及总结的体会
wangle79
博客等级 码龄21年 0粉丝 10原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值