Erase-remove idiom: what happens when remove return past-the-end-iterator?

1.9k Views Asked by At

I got this question when I was reading erase-remove idiom (item 32) from Scott Meyers "Effective STL” book.

vector<int> v; 
...
v.erase(remove(v.begin(), v.end(), 99), v.end());

remove basically returns the "new logical end” and elements of the original range that start at the "new logical end" of the range and continue until the real end of the range are the elements to be erased from container.

Sounds good. Now, let me ask my question:

In the above example, remove can return v.end() if 99 is not found in the vector v. It is basically passing past-the-end-iterator to erase method.

  1. What happens when past-the-end-iterator is passed to the erase method? Does standard says it a UB?
  2. If it is undefined behavior, then erase-remove idiom example in Scott Meyer’s book should have looked like:

  vector<int> v; 
    ...
    vector<int>::iterator newEndIter = remove(v.begin(), v.end(), 99);
    if(newEndIter != v.end() )
    {
     v.erase(newEndIter, v.end();
    }  

Any ideas on this?

3

There are 3 best solutions below

1
On

I would think v.erase(v.end(), v.end()) would be well defined and erase nothing.

4
On

The C++ standard says that the erase(q1,q2) member "erases the elements in the range [q1,q2)" (cf. section 23.1.1). Since the range excludes the last element,

v.erase(v.end(), v.end());

is valid and erases nothing.

0
On

C++ Reference claims:

The iterator first does not need to be dereferenceable if first==last: erasing an empty range is a no-op.