Boris Dalstein
Boris Dalstein

Reputation: 7748

What iterator does vector::erase() return if passed an empty range?

According to cppreference.com and cplusplus.com, the function std::erase(first, last) returns "an iterator following the last removed element".

However, it is unclear what the return value is in the special case when there is no removed element at all, that is, when first == last (empty range). As of Jan 19, 2020, none of the above sources mention this special case.

For example, in the following code:

std::vector<int> v{1, 2, 3, 4};
auto it1 = v.erase(v.begin(), v.begin());
auto it2 = v.erase(v.end(), v.end());

What will be the value of it1 and it2?

Upvotes: 8

Views: 971

Answers (1)

Boris Dalstein
Boris Dalstein

Reputation: 7748

This is specified in [sequence.reqmts]:

The iterator returned by a.erase(q1, q2) points to the element pointed to by q2 prior to any elements being erased. If no such element exists, a.end() is returned.

(Note: I linked the C++17 final working draft, but this wording exists since at least C++98, see comment by @Peter)

So we should have it1 == v.begin() and it2 == v.end().

Live test:

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> v{1, 2, 3, 4};
    auto it1 = v.erase(v.begin(), v.begin());
    auto it2 = v.erase(v.end(), v.end());
    std::cout << std::distance(v.begin(), it1) << std::endl;
    std::cout << std::distance(v.begin(), it2) << std::endl;
}

Output:

0
4

To clarify this behavior, I have updated the cppreference documentation, which is now:

iterator erase( const_iterator pos );
iterator erase( const_iterator first, const_iterator last );

Return Value

Iterator following the last removed element.

If pos refers to the last element, then the end() iterator is returned.

If last==end() prior to removal, then the updated end() iterator is returned.

If [first, last) is an empty range, then last is returned.

Upvotes: 10

Related Questions