vector:

如同一般复合类型一样,vector 迭代器也可以声明成:

const vector<int>::iterator it1 = v.begin();
vector<int>::iterator const it2 = v.begin();

但在一般复合类型中 it1 通常是底层 const,ti2是 顶层 const。但在上面两条声明语句中 it1, it2 都是顶层 const,即 it1, it2 本身的值不能改变(不能指向其它对象),而其所指对象的值是可以改变的。既然不能通过声明迭代器 it1 的形式得到底层 const,那么就需要有其它方法来达成咯。这就是 const_iterator。

vector<int>::const_iterator it3 = v.begin();

it3 会是一个底层 const,即其所指对象可以改变,但不能改变其所指对象的值。

     std::vector<int> v(, );
const vector<int>::iterator it1 = v.begin();
// it1++;//改变it1的值是非法的
*it1 += ;
cout << *it1 << endl;//输出2 vector<int>::iterator const it2 = v.begin();
// it2 = v.end();//改变it2的值是非法的
cout << *it2 << endl;//输出2
*it2 += ;
cout << *it2 << endl;//输出3 vector<int>::const_iterator it3 = v.begin();
// *it3 += 1;//改变it3所指对象的值是非法的
it3++;//让it3指向v中第一个元素的下一个元素
cout << *it3 << endl;//输出1 const vector<int>::const_iterator it4 = v.begin();
// it4++;//改变it4的值是非法的
// *it4 += 1;//改变it4所指对象的值是非法的 vector<int>::const_iterator const it5 = v.begin();
// it5++;//改变it5的值是非法的
// *it5 += 1;//改变it5所指对象的值是非法的

set:

     set<int> s;
s.insert();
s.insert();
set<int>::iterator it = s.begin();
cout << *it << endl;//输出1
// *it += 1;//set里面的元素本身是常量,不可改变

在上面的代码中,若加上 it += 1,则会报错:

可以发现 set 的元素是带有 const 限定符的。

因此要修改 set 里面某个元素的值的话一般需要先删除需要修改的那个元素,再插入目标值,需要 log(n) 的时间。

当然也可以通过 const_cast 来解除 set 迭代器的底层 const:

     set<int> s;
s.insert();
s.insert();
s.insert(); const set<int>::iterator it = s.begin();
int &cnt = const_cast<int&>(*it);//cnt为it所指对象的引用, 但cnt不具有底层const
cnt += ;
cout << *it << endl;//输出101
cout << cnt << endl;//输出101
for(auto i : s){
cout << i << " ";//输出 101 10 100 (set类型对象s的有序性被破坏了)
}
cout << endl; s.insert();
cout << *s.begin() << endl;
for(auto i : s){
cout << i << " ";//输出 1 101 10 100
}
cout << endl;

上例中虽然用 const_cast 去掉了迭代器 it 的底层 const,但是却破坏了 s 的有序性,显然不是一个好的办法。因此用 const_cast 改变对象的底层 const 时一定要慎之又慎。

和 vector 迭代器类似的是,const 作用于 set 迭代器也是顶层 const,而 set 又自带底层 const,所以用 const 限定的 set 迭代器既不能改变所指对象,也不能改变所指对象的值。而 const_iterator 的作用则和 set 迭代器自带的底层 const 重复了。

     set<int> s;
s.insert();
s.insert();
s.insert(); const set<int>::iterator it1 = s.begin();
cout << *it1 << endl;//输出1
// it1++;//非法操作
// *it1 += 1;//非法操作 set<int>::iterator const it2 = s.begin();
cout << *it2 << endl;//输出1
// it2++;//非法操作
// *it2 += 1;//非法操作 set<int>::const_iterator it3 = s.begin();
// *it3 += 1;//非法操作
it3++;
cout << *it3 << endl;//输出10

map:

和 set 类似,map 的迭代器也带有底层 const,不同的是 map 迭代器中只有 key 是 const 的。

     map<int, int> mp;
mp[] = ;
map<int, int>::iterator it = mp.begin();
cout << (*it).first << " " << (*it).second << endl;//输出1 2
(*it).second += ;
// (*it).first += 1;//有const修饰符,不能改变
cout << (*it).first << " " << (*it).second << endl;//输出1 3

如果加上 (*it).first += 1; 则会报错:

const 作用于 map 也是顶层 const,而 const_iterator 作用于 map 是底层 const。map 迭代器指向的一个 pair 类型的对象。map 迭代器只有 key(pair 的第一个元素)是 const 的。使用 const_iterator 后则整个 pair 都是 const 的。

     map<int, int> mp;
mp[] = ;
mp[] = ; const map<int, int>::iterator it1 = mp.begin();
// it1 = mp.end();//非法操作
// it1->first += 1;//非法操作
it1->second += ;
cout << it1->first << " " << it1->second << endl;//输出1 3 map<int, int>::iterator const it2 = mp.begin();
// it2 = mp.end();//非法操作
// it2->first += 1;//非法操作
it2->second += ;
cout << it2->first << " " << it2->second << endl;//输出1 4 map<int, int>::const_iterator it3 = mp.begin();
it3 = --mp.end();//end是尾后迭代器
// it3->first += 1;//非法操作
// it3->second += 1;//非法操作,使用const_iterator修饰后it3具有底层const const map<int, int>::const_iterator it4 = mp.begin();
// it4 = --mp.end();//非法操作
// it4->first += 1;//非法操作
// it4->second += 1;//非法操作 map<int, int>::const_iterator const it5 = mp.begin();
// it5 = --mp.end();//非法操作
// it5->first += 1;//非法操作
// it5->second += 1;//非法操作

如果试图给 const_iterator 迭代器改变所指对象的值,则会报错:

提示 std::pair<const int, int>::second 是只读的。

const 迭代器和 const_iterator (vector/set/map)的更多相关文章

  1. C++ ------ const迭代器 和 const_iterator的区别

    const迭代器,顾名思义,就是不能改变的迭代器,是常量,其性质是由const决定的.比如说我们这样定义一个const迭代器. vector<,); const vector<int> ...

  2. VC++ 迭代器 iterator, const_iterator, const iterator

    迭代器 iterator, const_iterator, const iterator 迭代器iterator的作用类似于指针. (1)iterator只有针对制定<类型>的容器才有效. ...

  3. STL review:vector & string & map & struct

    I.vector 1.头文件:#include<vector>                        //容器vector是一个能实现随机存取.插入删除的动态数组,还可以当栈使. ...

  4. C/C++解题常用STL大礼包 含vector,map,set,queue(含优先队列) ,stack的常用用法

    每次忘记都去查,真难啊 /* C/C++解题常用STL大礼包 含vector,map,set,queue(含优先队列) ,stack的常用用法 */ /* vector常用用法 */ //头文件 #i ...

  5. C++STL(vector,map,set,list)成员函数整理

    / *最近ACM比赛,用到的时候忘记成员函数了,贼尴尬,给以后比赛做下准备 */ LIST: 构造函数 list<int> c0; //空链表 list<int> c1(3); ...

  6. pair在vector和map中的使用

    #include <iostream> #include <cstdio> #include <cstring> #include <stack> #i ...

  7. Java中List,ArrayList、Vector,map,HashTable,HashMap区别用法

    Java中List,ArrayList.Vector,map,HashTable,HashMap区别用法 标签: vectorhashmaplistjavaiteratorinteger ArrayL ...

  8. paip.提升性能---list,arraylist,vector,linkedlist,map的选用..

    paip.提升性能---list,arraylist,vector,linkedlist,map的选用.. arraylist,vector基本一样,但是,vector线程安全的. 作者Attilax ...

  9. cocos2dx 3.x Value、Vector和Map意识

    1. Value cocos2d::Value 这包括一个非常大的数字原生类型(int,float,double,bool,unsigned char,char* 和 std::string)外 加s ...

随机推荐

  1. IDA Pro 权威指南学习笔记(五) - IDA 主要的数据显示窗口

    在默认配置下,IDA(从 6.1 版开始)会在对新二进制文件的初始加载和分析阶段创建 7 个显示窗口 3 个立即可见的窗口分别为 IDA-View 窗口.函数窗口和消息输出窗口 可以通过 View - ...

  2. HALCON 算子函数(四) File

    HALCON 算子函数——Chapter 4 : File 4.1 Images 1. read_image 功能:读取有不同文件格式的图像. 2. read_sequence 功能:读取图像. 3. ...

  3. leetcode892

    这道题因为有0的情况,因此不能使用投影的方法,需要遍历每一个元素,单独处理. class Solution { public: int surfaceArea(vector<vector< ...

  4. IE bug之location.href没有referer

    使用js实现跳转一般会用 location.href="www.google.com"; 这样在一般的浏览器中可以在服务器端正常的获取referer,但是如果是IE浏览器就不正常了 ...

  5. 第一篇&nbsp;UCOS介绍

    第一篇 UCOS介绍 这个大家都知道.呵呵.考虑到咱们学习的完整性还是在这里唠叨一下.让大家再熟悉一下.高手们忍耐一下吧! uC/OS II(Micro Control Operation Syste ...

  6. 【原】Coursera—Andrew Ng机器学习—课程笔记 Lecture 6_Logistic Regression 逻辑回归

    Lecture6 Logistic Regression 逻辑回归 6.1 分类问题 Classification6.2 假设表示 Hypothesis Representation6.3 决策边界 ...

  7. 服务器发送邮件出现Could not connect to SMTP host错误 解决办法

    服务器发送邮件出现Could not connect to SMTP host错误 解决办法 功夫不负有心人,最后了解到,除了google的smtp服务器收到请求“smtp”会接受,其他服务器比如qq ...

  8. SpringAOP01 利用AOP实现权限验证、利用权限验证服务实现权限验证

    1 编程范式 1.1 面向过程 1.2 面向对象 1.3 面向切面编程 1.4 函数式编程 1.5 事件驱动编程 2 什么是面向切面编程 2.1 是一种编程范式,而不是一种编程语言 2.2 解决一些特 ...

  9. SQL Server误区30日谈 第26天 SQL Server中存在真正的“事务嵌套”

    误区 #26: SQL Server中存在真正的“事务嵌套”错误 嵌套事务可不会像其语法表现的那样看起来允许事务嵌套.我真不知道为什么有人会这样写代码,我唯一能够想到的就是某个哥们对SQL Serve ...

  10. 解决在Python中使用Win32api报错的问题,No module named win32api

    一.系统环境 操作系统: Win7 64位 Python:3.7.0 二.在使用import win32api时,报错:No module named win32api 网上查到有下面解决办法: 方法 ...