vector::erase 删除单个元素需配合迭代器,不能直接传值;正确做法是先用 std::find 查找再 erase,并检查迭代器有效性;批量删用 remove-erase 惯用法;按条件删用 remove_if;注意迭代器失效与性能陷阱。

vector::erase 删除单个元素要配合迭代器使用
直接用 erase 删除某个值(比如数字 5)会失败,因为 erase 不接受值参数,只接受迭代器。常见错误是写成 v.erase(5),这会删掉第 5 个位置的元素,不是值为 5 的元素。
正确做法是先用 std::find 找到目标值的迭代器,再传给 erase:
auto it = std::find(v.begin(), v.end(), 5);
if (it != v.end()) {
v.erase(it);
}
- 必须检查
it != v.end(),否则对未找到的end()调用erase是未定义行为 -
erase返回被删除元素后一个位置的迭代器(C++11 起),可用来继续遍历,但单删时通常不需要 - 删除后,原迭代器失效,后续不能再用
it访问或递增
一次性删除所有匹配值要用 remove-erase 惯用法
想删掉 vector 中所有值为 5 的元素?不能循环调用 find + erase,因为每次 erase 都会移动后续元素,导致迭代器失效、漏删或越界。
标准解法是 std::remove + erase 组合:
立即学习“C++免费学习笔记(深入)”;
v.erase(std::remove(v.begin(), v.end(), 5), v.end());
-
std::remove不真正删除,只是把不匹配的元素前移,并返回新逻辑结尾的迭代器 -
erase接收这个迭代器和v.end(),批量擦除“被覆盖”区域(即原末尾多余部分) - 该操作时间复杂度 O(n),只遍历一次,比反复查找+删除高效且安全
按条件删除(比如大于 10 的元素)得用 remove_if
当删除逻辑无法用等值判断(如“删掉所有偶数”“删掉长度小于 3 的字符串”),就得换 std::remove_if:
v.erase(std::remove_if(v.begin(), v.end(), [](int x) { return x > 10; }), v.end());
- lambda 或函数对象返回
true的元素会被“移走”,最终由erase清理 - 注意:
remove_if同样不改变容器大小,必须配erase才真正收缩内存 - 如果需要保留原始顺序,这个方法天然满足;若顺序无关,有时用反向遍历 + 单次
erase更直观(但 remove_if 更通用)
删除时要注意迭代器失效和性能陷阱
erase 对 vector 来说开销不小——它会把被删元素之后的所有元素向前复制。频繁在头部或中间删除,性能会明显下降。
- 在尾部删除用
pop_back(),O(1),不涉及移动 - 需高频随机删除时,考虑换
std::list或std::deque(但失去随机访问) - 用索引循环删除(如 for(int i=0; i
- 用正向迭代器循环删除也危险,除非你手动管理迭代器(如
it = v.erase(it)),但不如 remove-erase 简洁可靠 - 用正向迭代器循环删除也危险,除非你手动管理迭代器(如
真正容易被忽略的是:vector 删除不会自动释放多余内存,容量(capacity())不变。如果删了大量元素又不再添加,可以用 std::vector 或 C++11 的 v.shrink_to_fit()(后者是请求,不保证成功)来回收内存。











