STL 容器使用 erase 遍历删除的坑

1. 序列式容器

序列式容器有 vector、deque、list,这里使用 vector 容器来举例说明
在 C++98 和 C++11 中 vector 的 erase 方法删除指定迭代器位置都是返回被删除位置的后一个位置的迭代器。
(vector 和 deque 底层是基于数组的存储方式)删除该迭代器后会导致后面的所有的迭代器失效。
(list 基于链表的存储方式)删除该迭代器之后导致该迭代器本身失效。

惯用删除的方法如下:

// 比如删除 vector<int> vecInt 里面值为0的数据
for(vector<int>::iterator it = vecInt.begin(); it != vecInt.end();)
{
    if(*it == 0)
    {
        it = vecInt.erase(it);
    }
    else
    {
        ++it;
    }
}

2. 关联式容器

关联式容器有 map、multimap、set、multiset,这里使用 map 容器来举例说明。
对于关联容器来说,如果某一个元素已经被删除,那么其对应的迭代器就失效了,不应该再被使用,否则会导致程序无定义的行为。
在 C++98 中 map 的 erase 删除指定迭代器上的位置没有返回值

void erase (iterator position);

在 C++98 中惯用删除的方法如下:

// 比如删除 map<int,int> mapInt 里面value值为0的数据
for(map<int,int>::iterator it = mapInt.begin(); it != mapInt.end();)
{
    if(it->second == 0)
    {
        mapInt.erase(it++);
    }
    else
    {
        ++it;
    }
}

在 C++11 中 map 的 erase 方法删除指定迭代器位置会返回被删除位置的后一个位置的迭代器。

iterator  erase (const_iterator position);

在 C++11 中惯用删除的方法如下:

// 比如删除 map<int,int> mapInt 里面value值为0的数据
for(auto it = mapInt.begin(); it != mapInt.end();)
{
    if(it->second == 0)
    {
        it = mapInt.erase(it);
    }
    else
    {
        ++it;
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容