remove-erase和find-erase之间有什么区别

ogg*_*ter 6 c++ stl

假设您想要按值从向量中删除单个元素.remove -erase有什么区别:

vector<int> v;
// add some values
vector<int>::iterator it = remove(v.begin(), v.end(), 5);
v.erase(it);
Run Code Online (Sandbox Code Playgroud)

并找到 - 擦除

vector<int> v;
// add some values
vector<int>::iterator it = find(v.begin(), v.end(), 5);
if(it != v.end())
{
  v.erase(it);
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*sop 13

您的删除 - 删除代码不正确.删除 - 擦除习语看起来像这样:

vector<int>::iterator it = remove(v.begin(), v.end(), 5);
v.erase(it, v.end());
Run Code Online (Sandbox Code Playgroud)

在这种情况下,它具有擦除所有等于5的值的效果,但它最小化了实现该值所需的复制量.

您的查找 - 擦除代码仅删除第一个等于5的值,因此它可以执行您想要的操作.

你的删除 - 擦除代码将所有不等于5的值移动到向量的前面(这就是做什么std::remove),擦除向量的其余元素之一,并在此之后留下任何剩余的元素与未指定的值(这也是什么)remove一样).如果向量不包含a 5开头,则它具有未定义的行为,因为在这种情况下remove将返回v.end().

所以,如果你只想删除几个等于5的单个元素,那么std::remove对你没用,因为它不保留(其他)5s.如果你想将非5值移到开头,将5个值移到最后,在删除5s中的第一个之前,那么你实际上可以做到这一点,而std::partition不是std::remove:

auto it = partition(v.begin(), v.end(), [](int i) { return i != 5; });
if (it != v.end()) v.erase(it);
Run Code Online (Sandbox Code Playgroud)

虽然,因为一个5和另一个一样好,你可以通过删除5s中的最后一个而不是第一个得到相同的结果,并且当它们不止一个时更有效:

auto it = partition(v.begin(), v.end(), [](int i) { return i != 5; });
if (it != v.end()) v.pop_back();
Run Code Online (Sandbox Code Playgroud)

如果你能以某种肯定的是,最初载体包含正好一个元素等于5(没有更多或更少),那么代码的两位做同样的事情.在这种情况下,您不需要it != v.end()在查找 - 擦除代码中进行测试,您会知道它不相等.你可以做到v.erase(find(v.begin(), v.end(), 5)).