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 }

可是,我仍是不建議這麼作,雖然這樣能夠使用迭代器進行修改元素的操做,但這與自己設計出來的思想相違背。

相關文章
相關標籤/搜索