array/vector/deque
这三种容器的内存空间连续,删除某一元素会导致其后所有元素前移。


如图所示,删除某一元素后,后面的元素全都前移了一位。此时it3指向end位置。

依照C++规定,包括it0在内的其后迭代器全部“失效”(尽管他们有些指向的是有效位置),对这些迭代器进行任何操作(解引用、调用符号重载函数等)都会抛出错误。
解决方法:erase函数将返回下一个有效位置的迭代器
例如:
//删除2之前的所有元素
vector<int> vec{ 0,1,2,3 };
for (auto it = vec.begin(); *it != 2;)
it = vec.erase(it);
list
对于使用链式存储结构的list,删除元素时就没有那么多顾虑了。
//删除2之前的所有元素
list<int> ls{ 0,1,2,3 };
for (auto it = ls.begin(); *it != 2;)
it = ls.erase(it);//ls.erase(it++)也可以
Q:为什么对于array/vector/deque删除元素时不能使用erase(it++)?
A:由于上述容器删除元素后其后元素将前移,所以erase(it++)将使it“后移”两格,这显然不符合it++的初衷,所以C++规范禁用了这一做法。

vec.erase(it++)语句不会报错,但之后一旦使用it就会抛出错误。
set/map
使用红黑树的set/map,本质上也是链式的存储结构,所以其迭代器失效情况同list
//删除2之前的所有元素
set<int> s{ 0,1,2,3 };
for (auto it = s.begin(); *it != 2;)
it = s.erase(it);//s.erase(it++)也可以
本文详细解析了C++中array、vector、deque、list、set和map等容器在删除元素时迭代器失效的问题。重点阐述了不同容器在元素删除后的迭代器状态变化及正确处理方法。

被折叠的 条评论
为什么被折叠?



