我们在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的更多相关文章

  1. STL中实现 iterator trail 的编程技巧

    STL中实现 iterator trail 的编程技巧 <泛型编程和 STL>笔记及思考. 这篇文章主要记录在 STL 中迭代器设计过程中出现的编程技巧,围绕的 STL 主题为 (迭代器特 ...

  2. STL中的set容器的一点总结

    1.关于set C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构 ...

  3. (转)STL中set的用法

    转载自here 1.关于set map容器是键-值对的集合,好比以人名为键的地址和电话号码.相反地,set容器只是单纯的键的集合.例如,某公司可能定义了一个名为bad_checks的set容器,用于记 ...

  4. STL中的set容器的一点总结(转)

    STL中的set容器的一点总结 1.关于set C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂 ...

  5. STL中的set使用方法详细!!!!

    1.关于set C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构 ...

  6. C++ STL中哈希表Map 与 hash_map 介绍

    0 为什么需要hash_map 用过map吧?map提供一个很常用的功能,那就是提供key-value的存储和查找功能.例如,我要记录一个人名和相应的存储,而且随时增加,要快速查找和修改: 岳不群-华 ...

  7. STL中的Vector相关用法

    STL中的Vector相关用法 标准库vector类型使用需要的头文件:#include <vector>. vector 是一个类模板,不是一种数据类型,vector<int> ...

  8. STL 中的map 与 hash_map的理解

    可以参考侯捷编著的<STL源码剖析> STL 中的map 与 hash_map的理解 1.STL的map底层是用红黑树存储的,查找时间复杂度是log(n)级别: 2.STL的hash_ma ...

  9. STL中的set容器的一点总结2

    http://blog.csdn.net/sunshinewave/article/details/8068326 1.关于set C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像 ...

随机推荐

  1. 一起来做webgame,《卡片魔兽》(一)基础战斗

    写在前面的话 这不是教程,只是博主在娱乐过程中的一些小结记录.博主水平有限,没有什么高级的东西,只是将一些小的知识点结合一下,做这么一个养成类型的卡片页面游戏(=.=!有点绕).做一个完整的游戏,涉及 ...

  2. Ionic + AngularJS

    Ionic Framework Ionic framework is the youngest in our top 5 stack, as the alpha was released in lat ...

  3. 一个简易的四则运算单元...(15.12.15 BUG更新)

    网上找的, 没有作者信息, 只能在这里感谢一下了, 支持标准写法的四则运算 --2015-12-15 修改了一个内存泄漏的BUG - Pop方法没有释放申请的内存 unit Base.Calculat ...

  4. shell-引号

    shell中的 ``(反引号) ''(单引号) ""(双引号) 反引号里面的内容赋给变量的时候 会以执行命令的方式给例如: str=`cat 1.txt` echo $str 就会 ...

  5. WordPress基础:小工具的使用

    通过外观->小工具对挂件区域的内容进行调整 比如添加个日历模块 保存后前台就会显示出来 如果不需要,反过来,把模块拖到左边就可以了.

  6. iOS 10的正确解锁方式

    在iOS 10上,锁屏状态通过按下电源键点亮屏幕之后,用手指轻触Home键,实际上手机是已经解锁了的,不信请看如下截图: 虽然手机已经解锁,但与iOS 9不同的是,此时手机还处在解锁界面而没有进入主屏 ...

  7. 升级win8.1后mysql服务不能启动的问题

    升级win8.1后发现服务列表中MySQL55不见了. 1. 先把服务恢复. mysql没有看到maitenance,找到安装文件 mysql-installer-community-5.6.12.0 ...

  8. angularjs中ng-controller中绑定对象

    <!DOCTYPE HTML><html ng-app="myApp"><head><meta http-equiv="Cont ...

  9. Single Responsibility Principle 单一职责原则

  10. 这是用过的"最差"树形插件

      这是用过的"最差"树形插件 !!! 或许大家听过一个bootstrap UI框架---ace皮肤.有兴趣的童鞋可以在线查看:https://www.iteblog.com/ac ...