Search code examples
c++stleraseremove-if

c++ vector; remove_if only removing a single value?


I'm supposed to implement a function that erases a range of values from containers. So

eraseRange(v, 1.5, 24);

for example would delete any value greater than 1.5 and less than 24 from the container v. And my function works perfectly for lists, where I use:

container.erase(remove_if(container.begin(), container.end(), rg));

Where rg checks if it's within the range (the implementation of that part isn't the issue, so I'm not going to elaborate on it).

However, when calling eraseRange for a vector, and using a similar method to erase the values, only the very first value gets erased. So if I were to have a vector with numbers from 1 to 10, and I called:

eraseRange(v, 3, 7);

Only 3 gets deleted.

Now this normally wouldn't be an issue, I would just use an iterator to check the values. Except for this specific exercise, for/while/do loops are explicitly forbidden...

So the problem seems to be with containers that have random access iterators. And I'm not sure what to implement as an alternative. Help?


Solution

  • There are several overloads of erase.

    One overload, the one you are using, takes a single iterator and erases the element pointed to by the iterator.

    The other overload, which you should be using, takes a range (a pair of iterators) and erases all of the elements in the range:

    c.erase(remove_if(c.begin(), c.end(), rg), c.end());
                                             ^^^^^^^^^
    

    [I'm not sure why your code "works perfectly for lists," as you say; std::list has the same two overloads of erase. Note that std::list also has a member function, remove_if, which provides a better implementation of the erase/remove algorithm specifically optimized for std::list (since std::list is implemented as a linked list, it can implement erase/remove without actually moving any objects).]