我们在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. Assign an Elastic IP Address to Your Instance

    By default, an instance in a nondefault VPC is not assigned a public IP address, and is private.You ...

  2. 浅谈java抽象类和接口

    第一次,写这个,没有把图片放上来,有兴趣的可以点击连接看原文 http://note.youdao.com/noteshare?id=aecbd52b9240f23c0954e8086b848a17 ...

  3. Cocoa Touch事件处理流程--响应者链

    Cocoa Touch事件处理流程--响应者链 作者:wangzz 原文地址:http://blog.csdn.net/wzzvictory/article/details/9264335 转载请注明 ...

  4. Yii2 关闭和打开csrf 验证 防止表单多次重复提交

    原文地址:http://blog.csdn.net/terry_water/article/details/52221007 1.在Yii2配置中配置所有:所有的controller都将关闭csrf验 ...

  5. 怎么搭建DC+SCCM 域环境(一)

    需要的软件: 1. SCCM 2012 SP1 2. SQL Server 2012 3. System ISO 4. ADK 环境搭建顺序: 1. 安装DC和SCCM 机器,并配置需要的IP.DNS ...

  6. springmvc 动态代理 JDK实现与模拟JDK纯手写实现。

    首先明白 动态代理和静态代理的区别: 静态代理:①持有被代理类的引用  ② 代理类一开始就被加载到内存中了(非常重要) 动态代理:JDK中的动态代理中的代理类是动态生成的.并且生成的动态代理类为$Pr ...

  7. C语言:使用命令行参数用字符串读取流和输出流进行文本文件的复制

    #include<stdio.h> int main(int argc,char *argv[]) { //检查用户的参数是否正确 if(argc<3) { printf(" ...

  8. DOS基础命令

    对服务(service)的操作 命令 功能 Net start 查看Windows开启的服务 Net stop [service name] 停止服务 net start [service name] ...

  9. socket编程进阶

    1.   动态导入模块 第一种方法(python解释器自己内部用的): 上图是我程序的目录结构 下面代码是动态导入模块3.py的源码: #AUTHOR:FAN lib_dir = __import__ ...

  10. javascript中的对象,原型,原型链和面向对象

    一.javascript中的属性.方法 1.首先,关于javascript中的函数/“方法”,说明两点: 1)如果访问的对象属性是一个函数,有些开发者容易认为该函数属于这个对象,因此把“属性访问”叫做 ...