C++ STL中的 iterator 和 const_iterator

咱们在C++中使用STL的容器时,常常会用到迭代器。使用迭代器能够很方便的进行容器元素遍历和修改等操做。编程

近日,在使用Visual Studio 2015编程的时候发现,set的迭代器直接就是const_iterator类型,而vector的迭代器则是普通的iterator类型,这是为何呢?今天就和你们一块儿来探究一下。数据结构

Set/Map类型spa

1 set<int>::iterator it1;
2 map<int,int>::iterator it2;
3 it1 = set1.begin();
4 *it1 = 1;

在Visual Studio 2010版本以上,声明一个集合或者一个哈希表的迭代器,虽然咱们写的是普通的iterator,可是其实它们都是const_iterator,即一个没法对元素进行修改操做的const引用(set取到的iterator则是const的,而map取到的iterator的key则是const的)。所以,若是使用该迭代器对容器中元素进行修改操做则会编译不经过(如第三、4行代码),对于map的迭代器同理。设计

为何不容许对元素进行修改?code

我认为这其中有两个缘由:blog

① 由于set和map这种类型的容器,须要根据key来保持有序或者是确保元素的惟一性,因此不容许用户直接对元素进行修改。若是容许用户在使用iterator时直接对元素进行修改间接的修改了元素的键值,颇有可能致使非惟一性或无序。排序

② 正是因为这种类型的容器须要保持元素的有序性,底层可能用了某种数据结构来保存(如:堆),若是频繁的修改元素,则内部可能须要屡次进行排序,致使效率低下。it

怎么对元素进行修改?io

既然普通的iterator没法直接对元素进行修改,那么咱们应该怎么作呢?下面就给出两种方法。编译

① 使用容器的erase()和insert()方法。若是想修改某个元素,那么直接删掉它,再将修改过的元素插入到原有的容器中。这种方法的缺点是效率过低。

② 使用const_cast

咱们都知道const_cast能够去掉任何底层const修饰,使得一个const变量成为非const的,这里咱们就使用这一点来消除iterator的const。

1 for (set<int>::iterator i = IntSet.begin(); i != IntSet.end(); i++)  
2 {  
3         int &item1 = const_cast<int&>(*i);  
4         //do something here    
5 }

可是,我仍是不建议这么作,虽然这样能够使用迭代器进行修改元素的操做,但这与自己设计出来的思想相违背。

相关文章
相关标签/搜索