C 迭代器之 反向迭代器

2021-06-10 03:23:44 字數 1369 閱讀 2767

反向迭代器(reverse iterator)是普通迭代器的介面卡,通過重新定義自增和自減操作,以達到按反序遍歷元素的目的。如果在標準演算法庫中用反向迭代器來代替普通的迭代器,那麼執行結果與正常情況下相反。除此之外,其用法與普通迭代器完全一樣,我們不作詳細討論。

這裡主要討論的是反向迭代器的乙個很特殊、也很容易出錯的性質,即它的「邏輯位置」與「物理位置」。先通過看乙個例子開始:

vectorvec;

for(vector::size_type i=1; i<10; ++i)

vector::iterator itr = vec.begin()+4;

cout<

cout<

如果你不了解反向迭代器這個特殊的性質的話,很容易誤認為結果一樣是5。但實際情況不是這樣,而是4,即前乙個位置處的元素!具體原因,即涉及到反向迭代器的「物理位置」與「邏輯位置」兩個概念。

我們都知道,乙個容器的範圍用普通迭代器表示為乙個「半開半閉」的區間。頭部為begin,指向容器第乙個元素的位置。末尾為end,指向最後乙個元素的下乙個位置,每個容器都提供了這樣乙個位置,儘管該位置不可引用,但卻是個合法的位址。相反,第乙個元素位置的前乙個位置容器卻沒有任何保證,比如對於vector和string來說,就是非法的位置。這裡我們說「合法」與「非法」,簡單來講,可以這樣認為,乙個合法的位置對於迭代器來說是可以達到的,像最後乙個元素的下乙個位置end()。而對於首元素的前乙個位置,迭代器是無法指向它的,begin()-1這個表示式會導致異常。因此,反向迭代器與普通迭代器在物理位置上保持了一一對應,即rbegin()對應普通迭代器的end()位置,rend()對應其begin()位置。

但是,為了讓反向迭代器與普通迭代器在概念上保持一致性,即begin()(反向迭代器對應為rbegin())對應第乙個元素(對於反向迭代器來說,最後乙個元素即第乙個元素),end()(反向迭代器對應為rend())對應最後乙個元素的下乙個位置,於是標準庫的設計者們想出這樣乙個方法,即反向迭代器的邏輯位置等於其物理位置的前乙個位置。換句話說,物理位置對應迭代器在記憶體中的實際位置,邏輯位置對應迭代器對應容器中元素的位置。這樣,對於rbegin()來說,它物理位置是容器最後乙個元素的下乙個位置,邏輯位置即容器最後乙個元素的位置(對反向迭代器來說就是第乙個元素元素的位置),同理rend()物理位置為容器第乙個元素位置,邏輯位置即第乙個位置的前乙個位置(依然不可解引用)。這樣,反向迭代器與普通迭代器便有了一致的概念,即「半開半閉」區間。更為直觀的演示如下圖:

這樣,開頭那個例子就很容易解釋了,反向迭代器被初始化為與前乙個普通迭代器一樣的物理位置(對應元素5),其邏輯位置即前乙個位置,因些通過解引用得到元素4.

c 之反向迭代器

include include include using namespace std int main cout include include include using namespace std int main vectorv a,a 10 vector reverse iterator ...

迭代器 反向迭代器

c primer 中文版第四版 第273頁 9.3.2 begin和end成員 begin和end操作產生指向容器內第乙個元素和最後乙個元素的下乙個位置的迭代器,如下所示。這兩個迭代器通常用於標記包含容器中所有元素的迭代範圍。c.begin 返回乙個迭代器,它指向容器c的第乙個元素 c.end 返回...

迭代器和反向迭代器,常量迭代器和非常量迭代器

迭代器的型別共有4種 iiterator,const iterator,reverse iterator,const reverse iterator include include include include using namespace std int main include inclu...