迭代器的使用

2021-06-14 05:35:38 字數 2368 閱讀 3971

先看下面的例子:

vector 的元素刪除

話頭從 container 的元素刪除說起。jyhuang 觀察到「如果 vector 或 list

的最後乙個元素符合刪除條件,程式會有問題」。他給我這樣乙個片段:

template

void print_elements(t elem)

void (*pfi)(int) = print_elements; // 函式指標,做為 function object 用

...int ia[7] = ;

vectorivec(ia, ia+7);

for_each(ivec.begin(), ivec.end(), pfi); // 0 1 2 3 4 5 6

for (vector::iterator it = ivec.begin(); it != ivec.end(); it++)

for_each(ivec.begin(), ivec.end(), pfi); // 0 2 4 6 正確!

如果把 array 和 vector 的初值改為:

int ia[8] = ;

vectorivec(ia, ia+8);

則上述程式會當掉。

●i don't think so...

我不相信 stl 會有這麼差勁的表現。所以多做了幾次測試如下。

(1) 把 array 和 vector 的初值改為:

int ia[7] = ;

vectorivec(ia, ia+7);

程式結果為 0 2 4 7。結果不對,但不會當掉。

(2) 把 array 和 vector 的初值改為:

int ia[7] = ;

vectorivec(ia, ia+7);

程式結果為 0 3 7 7。錯得離譜,但不會當掉。

(3) 把 array 和 vector 的初值改為:

int ia[7] = ;

vectorivec(ia, ia+7);

程式執行時會當掉。

我於是多做了一些觀察,然後知道,上述這些動作根本上是完全

不對的。第乙個 sample 之執行結果正確,完全是湊巧。

問題不在「最後乙個元素是否符合刪除條件」,而在對 iterator

特性的認識。當我們做了 ivec.erase(it) 動作,vector 便動態

減縮了乙個元素(邏輯上,後繼元素向前遞補),而 it 不變。

之後 for 迴圈的第三部份述句要求 it++,造成 it 跳過了乙個元素...。

看例項:

(1) 初值為

第一次迭代,發現是偶數: ★ 以下以 e 表示 end()

0 1 2 3 4 5 6 e

^第二次迭代,發現是奇數:

0 1 2 3 4 5 6 e

^於是將  '1'  刪除,vector 變成:

0 2 3 4 5 6 e

^第三次迭代,發現是奇數(這時已發生錯誤,因為 '2' 被跳過,沒有檢查):

0 2 3 4 5 6 e

^於是將 '3' 刪除,vector 變成:

0 2 4 5 6 e

^第四次迭代,發現是奇數(這時已發生錯誤,因為 '4' 被跳過,沒有檢查):

0 2 4 5 6 e

^於是將 '5' 刪除,vector 變成:

0 2 4 6 e

^第五次迭代,發現 it == vec.end(),於是跳離迴圈:

0 2 4 6 e

^此時 vector 剩餘 0 2 4 6,陰錯陽差地與正確結果吻合。

(2) 初值為

第一次迭代,發現是偶數: ★ 以下以 e 表示 end()

0 2 4 6 0 4 7 e

^第二次迭代,發現是偶數:

0 2 4 6 0 4 7 e

^第三次迭代,發現是偶數:

0 2 4 6 0 4 7 e

^第四次迭代,發現是偶數:

0 2 4 6 0 4 7 e

^第五次迭代,發現是偶數:

0 2 4 6 0 4 7 e

^第六次迭代,發現是偶數:

0 2 4 6 0 4 7 e

^第七次迭代,發現是奇數:

0 2 4 6 0 4 7 e

^於是將 '7' 刪除,vector 變成:

0 2 4 6 0 4 e

^第八次迭代,it 越過了 end(),造成越界錯誤。迴圈何時結束,未可知也:

0 2 4 6 0 4 e ? ? ? ? ? ?

^我的結論:

iterator 只適用於在「不更動 container 布局」的條件下,對 container 做巡訪動作。否則,對 iterator 的取值行為,直觀下極易誤用。

原創**:

迭代器的使用

參考 stl中的迭代器有五種型別,不同的容器可支援不同的迭代器 1.vector,支援隨機迭代器 include include include using namespace std int main cout endl cout endl vector iterator iter1 charve...

迭代器的使用

迭代器 iterator 有時又稱游標 cursor 是程式設計的軟體設計模式,他是專門為訪問容器而設計的一種資料結構,他實際是對訪問容器這一操作進行了封裝。也有一種說法是迭代器是指標的封裝。和智慧型指標有點相似。迭代器是一種物件,他用來遍歷標準模板庫容器中的部分或全部元素,每個迭代器物件代表容器中...

使用迭代器

建立迭代器最常用的方法是對 ienumerable 介面實現 getenumerator 方法,例如 c 複製 public system.collections.ienumerator getenumerator getenumerator 方法的存在使得型別成為可列舉的型別,並允許使用 fore...