Home > Enterprise >  Correct way to invoke remove_if [duplicate]
Correct way to invoke remove_if [duplicate]

Time:10-02

In the following sample code remove_if is supposed to delete all even numbers but it is not working as I expect. I am obviously doing something wrong since the output continues to show some even numbers, towards the end.

#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;
}

output 11 13 15 17 19 16 17 18 19 20 22

CodePudding user response:

std::remove_if only move the elements that need to be removed to the end of the container, you still need to use vector::erase to actually erase them.

If your compiler supports C 20, then I recommend using std::erase_if which is more intuitive and less error-prone:

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

Demo.

CodePudding user response:

remove_if returns an iterator - which will be the end of the rearranged items.

You can change you for loop to stop when it gets to the new end.

CodePudding user response:

std::remove_if returns an iterator to the first element removed. In other words, everything before the iterator is evaluated to be false.

Have a look at the reference, especially the Return value paragraph.

For us, this means we have to iterate to returned iterator (the new end) if we want to print the odd values -- or we erase all elements from the returned iterator to 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;
}
  • Related