在實際的應用中,會碰到需要遍歷容器中的元素,並且在判斷某些的條件後,將某個元素從容器中清除的場景:
#include <stdio.h>
#include <map>
#include <set>
#include <list>
#include <vector>
#include <deque>
template<class T>
void del(T t, int pos)
{
// 測試循環遍歷中的刪除操作
int i = 0;
for (typename T::iterator it = t.begin(); it != t.end(); ++i)
{
printf("%d ", *it);
if (i == pos)
{
t.erase(it++);
}
else
++it;
}
printf("\n");
}
int main()
{
std::map<int, int> mp;
std::set<int> st;
std::list<int> lt;
std::vector<int> vec;
std::deque<int> dque;
for (int i = 0; i < 10; ++i)
{
mp.insert(std::make_pair(i, i));
st.insert(i);
lt.push_back(i);
vec.push_back(i);
dque.push_back(i);
}
del(mp, 5);
del(st, 5);
del(lt, 5);
del(vec, 5);
del(dque, 5);
return 0;
}
注意上面的代碼,it++或者++it,並不是發生在for循環頭裏面,而是在for循環體內,而當要進行刪除時,應該使用
t.erase(it++);
it++這個重載操作會使it後移,並返回當前迭代位置。
運行上面的代碼後,map、set、list正確輸出了值,而當運行到vec或者dque後,會發生斷言崩潰等情況,原因是執行erase後,it已經無效,導致下次循環時,取值失敗。
因此需要注意以上這種循環遍歷中刪除元素,且不影響繼續遍歷的方式可以用於關係容器中(map,list,set等),而線性容器(vector,deque等)就會出現問題。