假設有一個list容器,順序存儲了0-9一個10個整數。現在要使用reverse_iterator迭代器來查找值為8和5的元素,並且將這兩個數刪除。先來看以下的解決方法:
1 #include <iostream> 2 #include <list> 3 using namespace std; 4 int main() 5 { 6 //MergeSortTest(); // 測試題目一,歸並排序 7 //movableWindowsTest();// 測試題目二,移動窗口,輸出窗口中的最小值 8 list<int> l; 9 for(int i = 0;i < 10;++i) 10 l.push_back(i);// 初始化容器存入0-9十個整數 11 list<int>::reverse_iterator it; 12 int count = 2;// 記錄剩下需要刪除元素的個數 13 for(it = l.rbegin();it != l.rend() && count; ++it) 14 { 15 if(*it == 8 || *it == 5) 16 { 17 list<int>::iterator temp(it.base());// 使用base函數返回一個普通迭代器,並以此刪除指向的元素 18 ++it; 19 l.erase(temp); 20 -- count; 21 } 22 } 23 return 0; 24 }
我們重點看17-19行三行代碼是否正確。這是我在不經過思考就順手寫出來的代碼,這三行代碼雖然編譯可以通過,但是是錯誤的。
首先,我們知道不可以直接使用reverse_iterator作為參數來調用erase函數的。
(錯誤思路)我的初始思路是希望通過it.base()函數來返回一個普通迭代器,並使用普通迭代器來刪除此元素,在刪除之前,先將迭代器指向下一個元素。
這樣做有兩個地方引起錯誤:
1、當it指向元素8時,it.base()返回的迭代器指向it的前一個位置,即指向元素9;
2、使用erase刪除it.base()后,it的值未定義,即刪除后,it的值不存在了,而不是原來++it的值。
針對錯誤1,我們可以改使用(++it).base()來返回指向正確位置的迭代器。(請注意不要使用++it.base(),這樣做修改返回值,是極不推薦的做法)。
針對錯誤2,我們需要知道,erase函數的返回值就是 刪除該元素后指向的下一個位置的迭代器。因此只要記錄下erase的返回值,就能正確獲得it的值。
根據以上兩點說法,將代碼13-21行修改為:
1 for(it = l.rbegin();it != l.rend() && count;) 2 { 3 if(*it == 8 || *it == 5) 4 { 5 list<int>::iterator iter = l.erase((++it).base());// 記錄刪除該元素后的指向下一個位置的迭代器(注意刪除8時,下一個是9) 6 it = list<int>::reverse_iterator(iter);// 將該迭代器轉換為reverse_iterator,此時it指向7 7 -- count; 8 } 9 else 10 ++it; 11 }
以上代碼變可以成功刪除容器中的5和8兩個元素,並使容器中存儲的為1,2,3,4,6,7,9.
到此,仍有一個需要特別留意的問題:上面的第5行代碼,刪除8時,得出的iter指向的“下一個元素”是9,而不是7。而第六行執行完以后,it指向的是7。
其實這個應該挺好理解,但是在下水平有限,不太會解釋。指出這一點是為了讓大家多留個神,否則容易給自己挖了個坑。詳細解釋請查閱其他資料。以下為正確的完整代碼寫法:

#include <iostream> #include <list> using namespace std; int main() { //MergeSortTest(); // 測試題目一,歸並排序 //movableWindowsTest();// 測試題目二,移動窗口,輸出窗口中的最小值 list<int> l; for(int i = 0;i < 10;++i) l.push_back(i);// 初始化容器存入0-9十個整數 list<int>::reverse_iterator it; int count = 2;// 記錄剩下需要刪除元素的個數 for(it = l.rbegin();it != l.rend() && count;) { if(*it == 8 || *it == 5) { list<int>::iterator iter = l.erase((++it).base());// 記錄刪除該元素后的指向下一個位置的迭代器(注意刪除8時,下一個是9) it = list<int>::reverse_iterator(iter);// 將該迭代器轉換為reverse_iterator,此時it指向7 -- count; } else ++it; } for(list<int>::iterator iter = l.begin();iter != l.end();++iter) cout << *iter << " "; cout << endl; return 0; }