This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
std::vector::erase[_if]
should be based on ranges remove
Section: 23.3.13.6 [vector.erasure] Status: New Submitter: Peter Kasting Opened: 2025-03-05 Last modified: 2025-03-09
Priority: Not Prioritized
View all issues with New status.
Discussion:
C++20 added std::vector::erase[_if]
. Per 23.3.13.6 [vector.erasure], these are equivalent
to a call to std::remove[_if]
followed by an appropriate erase
.
std::remove_if
is specified (by 26.7.8 [alg.remove]) as invoking
its predicate as pred(*i)
, while std::ranges::remove_if
uses the more flexible
invoke(pred, invoke(proj, *i))
. Disregarding the projection, the latter allows the use of member function
pointers as predicates, while the former does not.
I assume the committee intentionally did not change the non-ranges version to use invoke
because it
caused a backwards-compatibility risk. (If I am mistaken and this was an oversight, perhaps this and
other non-ranges algorithms that take predicates should be updated to use invoke() to invoke them.)
If that's true, though, it's perplexing why a new-to-c++20 function like std::vector::erase_if
should suffer the same drawback.
Proposed resolution:
This wording is relative to N5001.
Modify 23.3.13.6 [vector.erasure] as indicated:
template<class T, class Allocator, class U = T> constexpr typename vector<T, Allocator>::size_type erase(vector<T, Allocator>& c, const U& value);-1- Effects: Equivalent to:
auto rit= ranges::remove(c.begin(), c.end(), value);auto r = distance(it, c.end());c.erase(r.begin()it, rc.end()); return r.size();template<class T, class Allocator, class Predicate> constexpr typename vector<T, Allocator>::size_type erase_if(vector<T, Allocator>& c, Predicate pred);-2- Effects: Equivalent to:
auto rit= ranges::remove_if(c.begin(), c.end(), pred);auto r = distance(it, c.end());c.erase(r.begin()it, rc.end()); return r.size();