C++擦除(如果存在)

C++ erase if exist

本文关键字:存在 如果 擦除 C++      更新时间:2023-10-16

我想用幂等方法从容器中删除元素(即,如果元素存在,则删除它,否则什么都不做,我可以随心所欲地这样做,结果是一样的(

据我所知,做map::erase是幂等的,即使密钥不存在也是安全的。我认为set是一样的。

那么向量(和类似的线性容器(呢?我知道这很有效:

auto it = std::find(vec.begin(), vec.end(), val);
if (it != vec.end())
vec.erase(it);

但我想知道是否有任何方法可以让我们不必手动检查it == vec.end()

根据cpp文档,vec.erase(vec.end())的行为没有定义,这意味着我们不能执行vec.erase(std::find(..))。有什么方法可以帮我做这个检查,这样我就可以用一行代码做remove_if_exist了吗?

这里的问题不是幂等性问题。它是一种数据访问模型。

关联容器(集合、映射等(与序列不同,因为它们有"键",这就是为什么您可以一次性执行按键查找和擦除操作。

序列没有键,所以您的比较是不公平的。请注意,关联容器上的等效操作(即按映射值查找—忽略集,因为奇怪的是,它的键它的值!(与序列容器一样冗长。

话虽如此,擦除-删除习惯用法确实非常麻烦(这样做是为了在尽可能多的算法中将"范围"与其父容器分离;但仍然如此(。remove_and_erase没有不存在的理由,但您必须将removeerase组合到一个实用程序函数中,自己创建它。

那么向量(以及类似的线性容器(呢?我知道这很有效:

你知道错了。您显示的代码也不是幂等的,因为后续调用可以多次修改同一个向量。所以真正的幂等调用是:

vec.erase( std::remove( vec.begin(), vec.end(), val ), vec.end() );

这是你想要的一条航线。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<int> vec {1, 2, 3, 4, 5, 6, 7, 8, 9};
vector<int>::iterator it;
((it = find(vec.begin(), vec.end(), 1)) == vec.end()) ? it : vec.erase(it);
for(int i : vec) 
cout << i << endl;
return 0;
}