C++ STL中的 iterator 和 const_iterator
我们在C++中使用STL的容器时,经常会用到迭代器。使用迭代器可以很方便的进行容器元素遍历和修改等操作。
近日,在使用Visual Studio 2015编程的时候发现,set的迭代器直接就是const_iterator类型,而vector的迭代器则是普通的iterator类型,这是为什么呢?今天就和大家一起来探究一下。
Set/Map类型
set<int>::iterator it1;
map<int,int>::iterator it2;
it1 = set1.begin();
*it1 = ;
在Visual Studio 2010版本以上,声明一个集合或者一个哈希表的迭代器,虽然我们写的是普通的iterator,但是其实它们都是const_iterator,即一个无法对元素进行修改操作的const引用(set取到的iterator则是const的,而map取到的iterator的key则是const的)。因此,如果使用该迭代器对容器中元素进行修改操作则会编译不通过(如第3、4行代码),对于map的迭代器同理。
为什么不允许对元素进行修改?
我认为这其中有两个原因:
① 因为set和map这种类型的容器,需要根据key来保持有序或者是确保元素的唯一性,所以不允许用户直接对元素进行修改。如果允许用户在使用iterator时直接对元素进行修改间接的修改了元素的键值,很有可能导致非唯一性或无序。
② 正是由于这种类型的容器需要保持元素的有序性,底层可能用了某种数据结构来保存(如:堆),如果频繁的修改元素,则内部可能需要多次进行排序,导致效率低下。
怎么对元素进行修改?
既然普通的iterator无法直接对元素进行修改,那么我们应该怎么做呢?下面就给出两种方法。
① 使用容器的erase()和insert()方法。如果想修改某个元素,那么直接删掉它,再将修改过的元素插入到原有的容器中。这种方法的缺点是效率太低。
② 使用const_cast。
我们都知道const_cast可以去掉任何底层const修饰,使得一个const变量成为非const的,这里我们就使用这一点来消除iterator的const。
for (set<int>::iterator i = IntSet.begin(); i != IntSet.end(); i++)
{
int &item1 = const_cast<int&>(*i);
//do something here
}
但是,我还是不建议这么做,虽然这样可以使用迭代器进行修改元素的操作,但这与本身设计出来的思想相违背。
C++ STL中的 iterator 和 const_iterator的更多相关文章
- STL中实现 iterator trail 的编程技巧
STL中实现 iterator trail 的编程技巧 <泛型编程和 STL>笔记及思考. 这篇文章主要记录在 STL 中迭代器设计过程中出现的编程技巧,围绕的 STL 主题为 (迭代器特 ...
- STL中的set容器的一点总结
1.关于set C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构 ...
- (转)STL中set的用法
转载自here 1.关于set map容器是键-值对的集合,好比以人名为键的地址和电话号码.相反地,set容器只是单纯的键的集合.例如,某公司可能定义了一个名为bad_checks的set容器,用于记 ...
- STL中的set容器的一点总结(转)
STL中的set容器的一点总结 1.关于set C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂 ...
- STL中的set使用方法详细!!!!
1.关于set C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构 ...
- C++ STL中哈希表Map 与 hash_map 介绍
0 为什么需要hash_map 用过map吧?map提供一个很常用的功能,那就是提供key-value的存储和查找功能.例如,我要记录一个人名和相应的存储,而且随时增加,要快速查找和修改: 岳不群-华 ...
- STL中的Vector相关用法
STL中的Vector相关用法 标准库vector类型使用需要的头文件:#include <vector>. vector 是一个类模板,不是一种数据类型,vector<int> ...
- STL 中的map 与 hash_map的理解
可以参考侯捷编著的<STL源码剖析> STL 中的map 与 hash_map的理解 1.STL的map底层是用红黑树存储的,查找时间复杂度是log(n)级别: 2.STL的hash_ma ...
- STL中的set容器的一点总结2
http://blog.csdn.net/sunshinewave/article/details/8068326 1.关于set C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像 ...
随机推荐
- yii2使用相关记录
#Yii::$app->user 是指yii\web\User这个类 #yii2在命令行下执行 D: cd D:\wnmp\php5 php D:\wnmp\www\yii2\yii test/ ...
- 《Linux内核分析》期末总结
Linux内核设计期中总结 版权声明:本文为博主原创文章,未经博主允许不得转载. 前八周博客汇总及总结 Linux内核设计第一周——从汇编语言出发理解计算机工作原理 我们学习了汇编语言的基础知识,这一 ...
- 使用jspatch进行热修复的实战总结
最近正式在线上项目中集成了jspatch进行热修复,这里做一个简单的总结. 工具篇: 首先,用xcode来编辑js非常困难,基本上没有缩进,完全需要手写:经过研究发现使用 Sublime text3 ...
- EntityFramework优缺点
高层视图: 改变在现有系统使用EntityFramework的优势是什么? • All -in-1框架的类映射表,需要编写映射代码, 并且是很难维护的. • 可维护性,易于理解的代码,无需创造大的数据 ...
- CentOS 7.2 安装配置Samba服务器
1背景 转Linux刚刚1年,vim操作还不能应对工程代码,之前一直都是Gnome桌面 + Clion 作开发环境,无奈在服务器上没有这样的环境, 看同事是(Windows)Source Insigh ...
- cordova IOS源码浅析
cordova封装了一套js和OC通信的代码,cordova.js下的iOSExex是关键的js去调原生的发起点. function iOSExec() { var successCallback, ...
- linear-gradient----渐变
CSS3 渐变(gradient)可以让你在两个或多个指定的颜色之间显示平稳的过渡. 以前,你必须使用图像来实现这些效果,现在通过使用 CSS3 的渐变(gradients)即可实现.此外,渐变效果的 ...
- Hibernate操作指南-搭建一个简单的示例(基于Java Persistence API JPA)
- iOS获取当前AppStore版本号与更新
- (void)checkUpdateWithAppID:(NSString *)appID success:(void (^)(NSDictionary *resultDic , BOOL isNe ...
- java.util.ConcurrentModificationException --map
key:3-key key:/v1.02-key Exception in thread "main" java.util.ConcurrentModificationExcept ...