std::unordered_set::erase(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

✨ std::unordered_set::erase β€” the manual page bestie πŸ’…

Okay so like, this is the <std::unordered_set::erase(3)> page from the C++ Standard Library manual, and honestly? It's giving "I can delete things from a hash set and look cute doing it" energy. Let me walk you through it, no cap. πŸŽ€


🌸 NAME 🌸

std::unordered_set::erase β€” literally the function that removes stuff, and its name is the same as the function, iconic.


πŸ¦‹ SYNOPSIS πŸ¦‹

Here's the tea, bestie β€” the overloads are a whole vibe and you need to know every single one:

    iterator erase( iterator pos );
(since C++11)
                                                                (until
C++23)
    iterator erase( iterator pos )
(since C++23)
        requires(!std::same_as<iterator, const_iterator>);
    iterator erase( const_iterator pos );                        (1) (2)
(since C++11)
    iterator erase( const_iterator first, const_iterator last );     (3)
(since C++11)
    size_type erase( const Key& key );                               (4)
(since C++11)
    template< class K >                                              (5)
(since C++23)
    size_type erase( K&& x );

πŸ’– DESCRIPTION πŸ’–

This function removes specified elements from the container. The order of the remaining elements is preserved β€” and honestly that's highkey important because it means you can erase individual elements while you're iterating through the container. Main character energy, fr fr. πŸ”₯

Let's break down each overload, because every single one matters:

  1. Overloads 1 and 2 β€” Removes the element at pos. Only one overload is provided if iterator and const_iterator are the same type. (They're two versions of the same vibe.)
  2. Overload 3 β€” Removes the elements in the range [first, last), which must be a valid range in *this. Periodt.
  3. Overload 4 β€” Removes the element (if one exists) with the key equivalent to key. If it's not there, no biggie, nothing happens.
  4. Overload 5 β€” Removes all elements with key that compares equivalent to the value x. But listen β€” this overload only participates in overload resolution if Hash::is_transparent and KeyEqual::is_transparent are valid and each denotes a type, and neither iterator nor const_iterator is implicitly convertible from K. This assumes that such Hash is callable with both K and Key type, and that the KeyEqual is transparent β€” which, together, allows calling this function without constructing an instance of Key. It's giving "optimized and smart," honestly. 🧚
Big important caveat, don't skip this: References and iterators to the erased elements are invalidated. Other iterators and references are not invalidated.
Also, and I cannot stress this enough: The iterator pos must be valid and dereferenceable. So the end() iterator (which is valid, but is not dereferenceable) cannot be used as a value for pos. It's literally invalid, bestie. Don't do it. πŸ’€

🌈 PARAMETERS 🌈

  • pos β€” iterator to the element to remove
  • first, last β€” range of elements to remove
  • key β€” key value of the elements to remove
  • x β€” a value of any type that can be transparently compared with a key denoting the elements to remove

πŸ’œ RETURN VALUE πŸ’œ

  • Overloads 1–3 β€” Iterator following the last removed element.
  • Overload 4 β€” Number of elements removed (0 or 1).
  • Overload 5 β€” Number of elements removed.

🫢 EXCEPTIONS 🫢

  • Overloads 1–3 β€” Throws nothing. Literally nothing. Chill.
  • Overloads 4, 5 β€” Any exceptions thrown by the Hash and KeyEqual object.

πŸ“ COMPLEXITY πŸ“

Given an instance c of unordered_set:

  • Overloads 1, 2 β€” Average case: constant, worst case: c.size().
  • Overload 3 β€” Average case: std::distance(first, last), worst case: c.size().
  • Overload 4 β€” Average case: c.count(key), worst case: c.size().
  • Overload 5 β€” Average case: c.count(x), worst case: c.size().

So like, usually fast, but worst case it's the whole set. Manage your expectations. 😭


🌟 NOTES 🌟

There's a feature-test macro for the heterogeneous erasure thing, and it's giving very specific:

Feature-test macroValueStdFeature
__cpp_lib_associative_heterogeneous_erasure202110L(C++23)Heterogeneous erasure in associative containers and unordered associative containers; overload (5)

Anyway, that table is the whole vibe. Moving on. ✨


🧚 EXAMPLE 🧚

// Run this code

#include <unordered_set>
#include <iostream>

int main()
{
    std::unordered_set<int> c = {1, 2, 3, 4, 1, 2, 3, 4};

    auto print = [&c]
    {
        std::cout << "c = { ";
        for (int n : c)
            std::cout << n << ' ';
        std::cout << "}\n";
    };
    print();

    std::cout << "Erase all odd numbers:\n";
    for (auto it = c.begin(); it != c.end();)
    {
        if (*it % 2 != 0)
            it = c.erase(it);
        else
            ++it;
    }
    print();

    std::cout << "Erase 1, erased count: " << c.erase(1) << '\n';
    std::cout << "Erase 2, erased count: " << c.erase(2) << '\n';
    std::cout << "Erase 2, erased count: " << c.erase(2) << '\n';
    print();
}

This example is so cute β€” it prints the set, erases all the odd numbers while iterating (the safe way, bestie), then erases specific keys and shows you the counts. Obsessed. πŸ‘‘


πŸ’€ DEFECT REPORTS πŸ’€

The following behavior-changing defect reports were applied retroactively to previously published C++ standards. Not me reading the lore of C++ fixes, but okay:

DRApplied toBehavior as publishedCorrect behavior
LWG 2059C++11there was ambiguity for overload (2)added overload (1)
LWG 2356C++11the order of non-equivalent elements that are not erased was not guaranteed to be preservedrequired to be preserved

So yeah, they fixed the ambiguity and made the preserved order a guarantee. Slay. πŸ’…


πŸ‘€ SEE ALSO πŸ‘€

  • clear β€” clears the contents (public member function). Lowkey does what it says on the tin.

That's the whole manual page, bestie β€” every overload, every caveat, every complexity note, all preserved. No details lost, just vibes added. πŸ’–

This page is from cppreference.com, dated 2024.06.10, and it's titled std::unordered_set::erase(3). ✨
πŸ“¦ where this page comes from