stl容器在循環遍歷中刪除元素的方式

在實際的應用中,會碰到需要遍歷容器中的元素,並且在判斷某些的條件後,將某個元素從容器中清除的場景:

#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等)就會出現問題。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章