本文的目的
erase在删除容器中的元素时,由于迭代器失效
会产生严重的错误;本文不讲太多的废话,直接从erase的使用性角度,总结了erase的通用使用套路,便于以后程序的开发。
容器分类
常见的容器有2大类,分别是:
节点式容器:(map, list, set)
顺序式容器:(vector,string,deque)
erase & 顺序式容器
在使用顺序式容器(vector,string,deque)遍历删除元素时,通常使用erase的返回值
获取已删除元素的下一个元素的迭代器位置,保证迭代器不失效。
① 错误的代码
std::vector<struct> mFriendVec;
...
std::vector<struct>::iterator iter = mFriendVec.begin();
for ( std::vector<struct>::iterator iter = mVector.begin();
iter != mFriendVec.end();
++iter
)
{
if ( willDelete(*iter) ) // if若成立,程序肯定崩溃,为什么呢?
mFriendVec.erase(iter);
}
② 正确的代码
std::vector<struct> mVector;
...
for ( std::vector<struct>::iterator iter = mVector.begin();
iter != mVector.end();
)
{
if ( willDelete(*iter) ) // 如果是待删除元素
{
//顺序式容器会使本身和后面的元素迭代器都失效,所以不能简单的++操作
iter = mVector.erase(iter); //erase返回值 = 指向已删除元素的下一个元素的iterator
}
else
{
++iter;
}
}
erase & 节点式容器
总结:无论是 节点式容器
还是顺序式容器
,在对迭代器iter进行删除时,我们都使用通用的万能公式
,代码见下。
std::list<int> List;
std::list<int>::iterator iter;
for( iter = List.begin(); iter != List.end(); )
{
if( WillDelete( *iter ) )
{
iter = List.erase(iter); //保存iterd的下一个元素
}
else
iter++;
}