Namespaces
Variants

std::erase, std::erase_if(std::list)

From cppreference.com
 
 
 
 
Defined in header <list>
template< class T, class Alloc, class U >
std::list<T, Alloc>::size_type
    erase( std::list<T, Alloc>& c, const U& value );
(1) (since C++20)
(until C++26)
template< class T, class Alloc, class U = T >
std::list<T, Alloc>::size_type
    erase( std::list<T, Alloc>& c, const U& value );
(since C++26)
template< class T, class Alloc, class Pred >
std::list<T, Alloc>::size_type
    erase_if( std::list<T, Alloc>& c, Pred pred );
(2) (since C++20)
1) Erases all elements that compare equal to value from the container. Equivalent to return c.remove_if([&](const auto& elem) -> bool { return elem == value; });.
2) Erases all elements that satisfy the predicate pred from the container. Equivalent to return c.remove_if(pred);.

Parameters

c - container from which to erase
value - value to be removed
pred - unary predicate which returns ​true if the element should be erased.

The expression pred(v) must be convertible to bool for every argument v of type (possibly const) T, regardless of value category, and must not modify v. Thus, a parameter type of T&is not allowed, nor is T unless for T a move is equivalent to a copy(since C++11). ​

Return value

The number of erased elements.

Complexity

Linear.

Notes

Unlike std::list::remove, erase accepts heterogeneous types and does not force a conversion to the container's value type before invoking the == operator.

Feature-test macro Value Std Feature
__cpp_lib_algorithm_default_value_type 202403 (C++26) List-initialization for algorithm (1)

Example

#include <complex>
#include <numeric>
#include <print>
#include <list>

template<typename T>
struct std::formatter<std::complex<T>, char>
{
    template<class ParseContext>
    constexpr ParseContext::iterator parse(ParseContext& ctx)
    {
        return ctx.begin();
    }

    template<class FmtContext>
    FmtContext::iterator format(const auto& s, FmtContext& ctx) const
    {
        auto out{std::format("({},{})", s.real(), s.imag())};
        return std::ranges::copy(std::move(out), ctx.out()).out;
    }
};

int main()
{
    std::list<char> cnt(10);
    std::iota(cnt.begin(), cnt.end(), '0');
    std::println("Initially, cnt = {}", cnt);

    std::erase(cnt, '3');
    std::println("After erase '3', cnt = {}", cnt);

    auto erased = std::erase_if(cnt, [](char x) { return (x - '0') % 2 == 0; });
    std::println("After erase all even numbers, cnt = {}", cnt);
    std::println("Erased even numbers: {}", erased);

    std::list<std::complex<double>> nums{{2, 2}, {4, 2}, {4, 8}, {4, 2}};
    #ifdef __cpp_lib_algorithm_default_value_type
        std::erase(nums, {4, 2});
    #else
        std::erase(nums, std::complex<double>{4, 2});
    #endif
    std::println("After erase {{4, 2}}, nums = {}", nums);
}

Output:

Initially, cnt = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
After erase '3', cnt = [0, 1, 2, 4, 5, 6, 7, 8, 9]
After erase all even numbers, cnt = [1, 5, 7, 9]
Erased even numbers: 5
After erase {4, 2}, nums = [(2,2), (4,8)]

Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
LWG 4135 C++20 the return type of the lambda predicate used
was deduced from predicate arguments
the return type is
explicitly specified as bool

See also

removes elements satisfying specific criteria
(public member function) [edit]
removes elements satisfying specific criteria
(function template & algorithm function object)[edit]