const 迭代器和 const_iterator (vector/set/map)

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,即其所指对象可以改变,但不能改变其所指对象的值。

 1     std::vector<int> v(10, 1);
 2     const vector<int>::iterator it1 = v.begin();
 3     // it1++;//改变it1的值是非法的
 4     *it1 += 1;
 5     cout << *it1 << endl;//输出2
 6 
 7     vector<int>::iterator const it2 = v.begin();
 8     // it2 = v.end();//改变it2的值是非法的
 9     cout << *it2 << endl;//输出2
10     *it2 += 1;
11     cout << *it2 << endl;//输出3
12 
13     vector<int>::const_iterator it3 = v.begin();
14     // *it3 += 1;//改变it3所指对象的值是非法的
15     it3++;//让it3指向v中第一个元素的下一个元素
16     cout << *it3 << endl;//输出1
17 
18     const vector<int>::const_iterator it4 = v.begin();
19     // it4++;//改变it4的值是非法的
20     // *it4 += 1;//改变it4所指对象的值是非法的
21 
22     vector<int>::const_iterator const it5 = v.begin();
23     // it5++;//改变it5的值是非法的
24     // *it5 += 1;//改变it5所指对象的值是非法的

 

set:

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

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

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

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

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

 1     set<int> s;
 2     s.insert(1);
 3     s.insert(10);
 4     s.insert(100);
 5 
 6     const set<int>::iterator it = s.begin();
 7     int &cnt = const_cast<int&>(*it);//cnt为it所指对象的引用, 但cnt不具有底层const
 8     cnt += 100;
 9     cout << *it << endl;//输出101
10     cout << cnt << endl;//输出101
11     for(auto i : s){
12         cout << i << " ";//输出 101 10 100 (set类型对象s的有序性被破坏了)
13     }
14     cout << endl;
15     
16     s.insert(1);
17     cout << *s.begin() << endl;
18     for(auto i : s){
19         cout << i << " ";//输出 1 101 10 100
20     }
21     cout << endl;

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

 

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

 1     set<int> s;
 2     s.insert(1);
 3     s.insert(10);
 4     s.insert(100);
 5 
 6     const set<int>::iterator it1 = s.begin();
 7     cout << *it1 << endl;//输出1
 8     // it1++;//非法操作
 9     // *it1 += 1;//非法操作
10 
11     set<int>::iterator const it2 = s.begin();
12     cout << *it2 << endl;//输出1
13     // it2++;//非法操作
14     // *it2 += 1;//非法操作
15 
16     set<int>::const_iterator it3 = s.begin();
17     // *it3 += 1;//非法操作
18     it3++;
19     cout << *it3 << endl;//输出10

 

map:

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

1     map<int, int> mp;
2     mp[1] = 2;
3     map<int, int>::iterator it = mp.begin();
4     cout << (*it).first << " " << (*it).second << endl;//输出1 2
5     (*it).second += 1;
6     // (*it).first += 1;//有const修饰符,不能改变
7     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 的。

 1     map<int, int> mp;
 2     mp[1] = 2;
 3     mp[2] = 3;
 4 
 5     const map<int, int>::iterator it1 = mp.begin();
 6     // it1 = mp.end();//非法操作
 7     // it1->first += 1;//非法操作
 8     it1->second += 1;
 9     cout << it1->first << " " << it1->second << endl;//输出1 3
10 
11     map<int, int>::iterator const it2 = mp.begin();
12     // it2 = mp.end();//非法操作
13     // it2->first += 1;//非法操作
14     it2->second += 1;
15     cout << it2->first << " " << it2->second << endl;//输出1 4
16 
17     map<int, int>::const_iterator it3 = mp.begin();
18     it3 = --mp.end();//end是尾后迭代器
19     // it3->first += 1;//非法操作
20     // it3->second += 1;//非法操作,使用const_iterator修饰后it3具有底层const
21 
22      const map<int, int>::const_iterator it4 = mp.begin();
23      // it4 = --mp.end();//非法操作
24      // it4->first += 1;//非法操作
25      // it4->second += 1;//非法操作
26 
27      map<int, int>::const_iterator const it5 = mp.begin();
28      // it5 = --mp.end();//非法操作
29      // it5->first += 1;//非法操作
30      // it5->second += 1;//非法操作

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

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

转载于:https://www.cnblogs.com/geloutingyu/p/8010993.html

前插型迭代器front_insert_iterator是STL中的一种迭代器类型,用于将元素插入容器的头部而不是尾部。它可以适用于所有支持push_front操作的容器,如list和deque等。 使用前提:需要使用一个支持push_front操作的容器,如list或deque。 定义方法:可以通过以下方式定义一个前插型迭代器front_insert_iterator: ``` template <typename Container> class front_insert_iterator { public: // 构造函数,接受一个容器作为参数 explicit front_insert_iterator(Container& x) : container(&x) {} // 重载运算符* front_insert_iterator& operator*() { return *this; } // 重载运算符++ front_insert_iterator& operator++() { return *this; } // 重载运算符++(后缀) front_insert_iterator operator++(int) { return *this; } // 重载运算符= front_insert_iterator& operator=(const typename Container::value_type& value) { container->push_front(value); return *this; } private: Container* container; }; ``` 其中,Container是容器的类型,value_type是容器中存储的元素类型。通过以上定义,就可以使用front_insert_iterator将元素插入容器的头部了。例如,可以通过以下方式将元素插入list的头部: ``` #include <iostream> #include <list> #include <iterator> using namespace std; int main() { list<int> mylist = {1, 2, 3, 4, 5}; front_insert_iterator<list<int>> myfront(mylist); *myfront = 6; ++myfront; *myfront = 7; for (auto i : mylist) { cout << i << " "; } return 0; } ``` 输出结果为:7 6 1 2 3 4 5。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值