news 2026/9/27 18:15:25

C++ vector 删除元素:erase-remove 惯用法与迭代器陷阱

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++ vector 删除元素:erase-remove 惯用法与迭代器陷阱

vector 删除元素:erase-remove 惯用法

  • 1. 问题背景
  • 2. std::remove 实际做了什么
  • 3. erase-remove 惯用法
  • 4. C++20 的更简洁写法
  • 5. 遍历时删除元素
  • 6. 删除多个元素的性能
  • 7. 常见误区
  • 8. 一页速查
  • 9. 总结

1. 问题背景

在 vector 中删除满足条件的元素,看起来像一个简单操作,但初学时很容易误解 std::remove。它的名字叫 remove,却不会真正改变容器大小。

2. std::remove 实际做了什么

std::remove 会把需要保留的元素移动到区间前部,并返回新的“逻辑结尾”。尾部仍然存在,只是内容处于未指定状态。

#include<algorithm>#include<vector>std::vector<int>values{1,0,2,0,3};autonewEnd=std::remove(values.begin(),values.end(),0);

执行后 values.size() 仍然是 5。要真正缩短容器,还需要 erase。

3. erase-remove 惯用法

values.erase(std::remove(values.begin(),values.end(),0),values.end());

这段代码分两步:remove 把保留元素移到前面;erase 删除从新逻辑结尾到真实结尾的元素。

按条件删除时使用 remove_if:

values.erase(std::remove_if(values.begin(),values.end(),[](intx){returnx<0;}),values.end());

4. C++20 的更简洁写法

C++20 为常用容器提供了 std::erase 和 std::erase_if。

std::erase(values,0);std::erase_if(values,[](intx){returnx<0;});

表达更直接,也不容易忘记第二步 erase。

5. 遍历时删除元素

需要边遍历边删除时,使用 erase 的返回值继续迭代。

for(autoit=values.begin();it!=values.end();){if(*it%2==0){it=values.erase(it);}else{++it;}}

vector::erase 会让删除位置及其后的迭代器、引用和指针失效,因此不能继续使用旧 it,也不要在 erase 后无条件再 ++it。

6. 删除多个元素的性能

循环中反复调用 erase 可能多次移动后续元素,最坏情况下成本很高。如果删除条件可以一次判断,erase-remove 或 erase_if 通常更高效,因为保留元素只需集中移动。

如果不要求保持原顺序,还可以用“与末尾交换再 pop_back”的方式进行 O(1) 单次删除:

values[index]=std::move(values.back());values.pop_back();

这种方法会改变元素顺序,只适合顺序不重要的场景。

7. 常见误区

  1. 只调用 remove,误以为 size 会变小;
  2. erase 后继续使用已经失效的迭代器;
  3. 在范围 for 中直接删除 vector 元素;
  4. 不考虑是否需要保持元素原顺序。

8. 一页速查

场景推荐写法
删除指定值(C++11)erase(remove(…), end())
按条件删除(C++11)erase(remove_if(…), end())
删除指定值(C++20)std::erase(container, value)
按条件删除(C++20)std::erase_if(container, pred)
遍历中删除it = container.erase(it)

9. 总结

std::remove 只调整元素位置,不负责缩小容器;真正删除要配合 erase。C++20 可优先使用 std::erase 和 std::erase_if。遍历中删除时必须接住 erase 返回的新迭代器,并牢记 vector 的迭代器失效规则。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/27 18:15:03

要不要弃坑 Cursor?一个重度用户用 TaoToken 统一 Key 后的真实纠结

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/27 18:14:12

Cursor Skill 实战:用 SKILL.md 与 MCP 配置 TaoToken 统一 Key 接入指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/27 18:13:20

AutoKaggle 多智能体框架配 TaoToken:settings.json 骨架与本地验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华