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. nodejs中的util.inspect.js

    util.inspect(object,[showHidden],[depth],[colors])是一个将任意对象转换 为字符串的方法,通常用于调试和错误输出.它至少接受一个参数 object,即要 ...

  2. ceph 创建和删除osd

    ceph 创建和删除osd 1.概述         本次主要是使用ceph-deploy工具和使用ceph的相关命令实现在主机上指定磁盘创建和删除osd,本次以主机172.16.1.96(主机名ha ...

  3. java成神之——java常识

    java常识 简单DOS命令 java基础名词 java编译和运行流程 Eclipse常用快捷键 Eclipse相关操作 java基本数据类型 java基本数据类型转换 java常用运算符 java流 ...

  4. 如何卸载win10的自带应用

    win10自带了好多应用,有些看起来不错,其实用起来不太方便哈(我的个人感觉),我们都更喜欢第三方应用,所以我们就来看看如何卸载这些自带应用.如图,是卸载完成后的Windows PowerShell: ...

  5. js 正则匹配 小结

    JS的正则表达式 rge.test(str) 检验目标对象中是否包含匹配模式,并相应的返回true或false   rge.source str.search(rge) 将返回一个整数值,指明这个匹配 ...

  6. Redhat 无线(Wifi)上网命令行配置

    小结两种命令行模式下配置无线wife的方法,实践测试通过(Red Hat Enterprise Linux release 6.0 Beta(Santiago)) 一.使用wpa_supplicant ...

  7. SqlServer——常见问题汇总

    1.存储过程手动执行正常,应用程序高并发允许时,数据成倍数增加 通常此类问题是由于存储过程中使用了永久表作为中间表,用以存储临时数据.当高并发时,比如同时执行3次,则同时往中间表中插入3倍的数据,得到 ...

  8. leetcode695

    public class Solution { public int MaxAreaOfIsland(int[,] grid) { ); ); bool[,] Visited = new bool[r ...

  9. 深入剖析SolrCloud(二)

    作者:洞庭散人 出处:http://phinecos.cnblogs.com/ 本博客遵从Creative Commons Attribution 3.0 License,若用于非商业目的,您可以自由 ...

  10. VS快捷键小收集

    1. Ctrl-M-O 折叠所有方法      Ctrl-M-M 折叠或展开当前方法     Ctrl-M-L 展开所有方法 2. 行编辑(复制,剪切,删除,交换) 当你在光标停留行使用快捷键Ctrl ...