【问题标题】:Correct way to invoke remove_if [duplicate]调用 remove_if 的正确方法 [重复]
【发布时间】:2021-11-23 03:27:33
【问题描述】:

在以下示例代码中,remove_if 应该删除所有偶数,但它没有按我预期的那样工作。我显然做错了什么,因为输出继续显示一些偶数,接近尾声。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

bool
myCond(int i) { return i % 2 == 0; }


int
main ()
{
  vector<int> myVector = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22};
  
  remove_if(myVector.begin(), myVector.end(), myCond);
  
  for(int i : myVector) cout << i << " ";
  cout << endl;
  return 0;
}

输出 11 13 15 17 19 16 17 18 19 20 22

【问题讨论】:

  • 你已经完成了erase-remove idiom 的一半。您仍然需要进行擦除。您必须经历这两个步骤的过程,这是一个实现细节。
  • Here is an example 说明步骤。

标签: c++ stl


【解决方案1】:

std::remove_if 只是将需要移除的元素移动到容器的末尾,你仍然需要使用vector::erase 来真正擦除它们。

如果你的编译器支持C++20,那么我推荐使用std::erase_if,这样更直观,更不容易出错:

vector<int> myVector = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22};
std::erase_if(myVector, myCond);

Demo.

【讨论】:

  • 任何阅读本文的人都会想知道为什么它会这样工作!答案基本上是这样您就可以混合搭配具有不同功能的不同容器(例如 remove_if)。不同的容器有不同的删除方式,所以你必须这样做而不是 remove_if 这样做。
【解决方案2】:

remove_if 返回一个迭代器 - 这将是重新排列的项目的结尾。

您可以将for 循环更改为在到达新结束时停止。

【讨论】:

  • 或者将std::vector&lt;int&gt;::erase() 与返回的交互器一起使用(看起来OP想要从向量中删除偶数元素)。
【解决方案3】:

std::remove_if 将迭代器返回到删除的第一个元素。换句话说,迭代器之前的所有内容都被评估为false

查看reference,尤其是Return value 段落。

对我们来说,这意味着如果我们想要打印奇数值,我们必须迭代到返回的迭代器(新端)——或者我们将返回的迭代器中的所有元素擦除到 end()

#include <iostream>
#include <vector>
#include <algorithm>

bool myCond(int i) { return i % 2 == 0; }

int main () {
  std::vector<int> myVector = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22};
  
  auto rm_it = std::remove_if(myVector.begin(), myVector.end(), myCond);
        
  // Possibility 1: Print odd values
  auto it = myVector.cbegin();
  for (; it != rm_it; ++it) std::cout << *it << " ";
  std::cout << std::endl;
  
  // Possibility 2: Erase values from the vector
  myVector.erase(rm_it, myVector.end());
  for(int i : myVector) std::cout << i << " ";
  std::cout << std::endl;
  
  return 0;
}

【讨论】:

  • remove_if 不是 partition,迭代器之后的所有内容都是移动值
猜你喜欢
  • 1970-01-01
  • 2011-04-15
  • 2019-12-18
  • 2014-05-08
  • 1970-01-01
  • 2018-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多