Question

It is commonly understood that a good way to fully delete desired items from a std::vector is the erase-remove idiom.

As noted in the above link (as of the date of this posting), in code the erase-remove idiom looks like this:

int main()
{
  // initialises a vector that holds the numbers from 0-9.
  std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

  // erase-remove idiom to completely eliminate the desired items from the vector
  v.erase( std::remove( std::begin(v), std::end(v), 5 ), std::end(v) ); 
}

I would like to know whether a resize-remove idiom is equivalent in terms of functionality and performance to the erase-remove idiom. Or, perhaps I am missing something obvious?

Is the following resize-remove idiom equivalent to the above erase-remove idiom?

int main()
{
  std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

  // Is this "resize-remove" approach equivalent to the "erase-remove" idiom?
  v.resize( std::remove( std::begin(v), std::end(v), 5 ) - v.begin() ); 
}
Was it helpful?

Solution

In my opinion, there are two reasons:

  1. std::remove algorithm requires only Forward Iterator, but - op requires Random Access Iterator.

  2. The result of std::remove means "the new end of container". Logically, we should erase [ "the new end of container" , "the old end of container" ).

OTHER TIPS

It is equivalent for std::vector, but not for std::list or other containers. Not sure if subtracting iterators is even possible for std::list, and even if it is, it is a O(N) operation.

It shouldn't make any difference; resize is defined in terms of insert and erase. But it is usually preferable to use the standard idiom, so that it can easily be recognized. And of course, the erase-remove idiom will work with any sequence container, and not just those which support resize. (All of the standard containers do seem to support resize, but it doesn't seem to be a requirement. So it might not be available on user defined containers, even though they support all required operations.)

In terms of performance: the resize must do one additional test, to determine whether it is erasing or inserting, but I can't imagine this making a significant impact.

I think erase in erase(first,last) guarantees that no elements before first are accessed or modified, while resize only guarantees this when no reallocation happens because of the resize.

Edit: as pointed out by others, such a reallocation will never happen, so there's no difference

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top