Вопрос

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?

Это было полезно?

Решение

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).]

Другие советы

remove_if returns a single iterator to "new last". That is its shuffled everything satisfying your predicate to past new last in the vector. Everything before new last doesn't satisfy your predicate, while everything past it does. Since you're executing the erase for only a single item from the vector, you're only removing the new last -- that is only one thing that satisfied your predicate. Instead you want to erase everything from new last -> end which is everything that satisfied your predicate

container.erase(
   remove_if(container.begin(), container.end(), rg), 
   container.end()
 );
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top