You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

vector的erase-remove惯用法处理不存在元素的问题及返回删除状态方法

关于erase-remove惯用法处理不存在元素的行为及返回删除状态的实现

好问题!我来给你详细拆解这两个点:

一、当前实现处理不存在元素的行为

你现在写的erase-remove代码其实完全安全,即使要删除的Person*不在_members里也不会出问题。

原理是这样的:std::remove会遍历整个vector,把所有不等于person_to_remove的元素往前挪,覆盖掉等于目标的元素。如果从头到尾都没找到匹配的指针,它会直接返回_members.end()——也就是容器原来的末尾迭代器。

接下来你调用erase(it, _members.end()),这时候传入的范围是[end(), end()),也就是一个空范围。vector的erase处理空范围时什么都不会做,既不会修改容器,也不会触发任何错误或未定义行为。

简单说:没找到要删的元素?那容器纹丝不动,程序正常跑。

二、修改实现来返回删除成功的布尔值

当然可以基于当前的实现改,而且有两种高效的方式:

方式1:通过比较容器大小变化判断

这种方法直观易懂,适合新手:

bool removeMember(Person* person_to_remove) {
    const size_t originalSize = _members.size();
    _members.erase(std::remove(_members.begin(), _members.end(), person_to_remove), _members.end());
    // 如果删除后size变小了,说明至少删了一个元素
    return _members.size() < originalSize;
}

方式2:利用std::remove的返回值判断

这种方法更高效(不用额外存储和比较size),是更地道的C++写法:

bool removeMember(Person* person_to_remove) {
    // 先调用remove,拿到标记删除区域起始的迭代器
    auto removeIt = std::remove(_members.begin(), _members.end(), person_to_remove);
    // 如果这个迭代器不等于原end,说明找到过要删除的元素
    const bool wasRemoved = removeIt != _members.end();
    // 执行实际的删除
    _members.erase(removeIt, _members.end());
    return wasRemoved;
}

两种方法都能正确处理多个相同指针的情况:如果vector里有多个相同的person_to_remove,都会返回true,因为确实有元素被删掉了。

内容的提问来源于stack exchange,提问作者A.D

火山引擎 最新活动