std::set::extract(3)
β¨ std::set::extract(3) β¨
okay bestie, gather round, because we're about to talk about the C++ Standard Library function std::set::extract, and honestly? it's kinda iconic. this is a std::set member function, and the way it lets you yoink nodes right out of a container is giving main character energy fr fr. no cap, this one's a banger. π
π SYNOPSIS π
okay so here's the vibe, look at these overloads:
node_type extract( const_iterator position ); (1) (since C++17)
node_type extract( const Key& k ); (2) (since C++17)
template< class K > (3) (since C++23)
node_type extract( K&& x );
- this one unlinks the node that holds the element that
positionis pointing at, and hands you back a node handle that owns it. slay. - if the container has an element with a key equivalent to
k, it unlinks that node from the container and returns a node handle that owns it. otherwise? you get an empty node handle. no drama, just emptiness. π - same as (2), literally the same. but this overload only participates in overload resolution if the qualified-id
Compare::is_transparentis valid and denotes a type, AND neitheriteratornorconst_iteratoris implicitly convertible fromK. why? because it lets you call this function without ever constructing an instance ofKey. efficiency queen. π
in either case (and this is important bestie), no elements are copied or moved β only the internal pointers of the container nodes are repointed (rebalancing may occur, as with erase()). it's giving minimal effort, maximum impact. π¦
extracting a node invalidates only the iterators to the extracted element. pointers and references to the extracted element remain valid, but they cannot be used while the element is owned by a node handle β they become usable again if the element is inserted into a container. so like, hold onto that reference, but don't @ it while it's in node-handle jail. π
πΈ PARAMETERS πΈ
positionβ a valid iterator into this container. gotta be valid, bestie, don't come at it with a broken iterator.kβ a key to identify the node to be extracted. it's giving "which one of y'all is this."xβ a value of any type that can be transparently compared with a key identifying the node to be extracted. transparent comparison? we love to see it. β¨
π RETURN VALUE π
a node handle that owns the extracted element. or, in the case of overloads (2,3) where the element isn't found? an empty node handle. it's giving "sorry babe, not here." π
π§ EXCEPTIONS π§
- throws nothing. literally nothing. icon behavior.
2, 3. any exceptions thrown by the Compare object. so if your comparator is messy, that's on you, not on extract. π
π COMPLEXITY π
- amortized constant. fast. effortless. the way it should be. π₯
2, 3. log(size()). logarithmic, which is still cute, just doing a little more work. ngl, still slaps.
π NOTES π
okay so this is the tea: extract is the only way to take a move-only object out of a set. the only way. periodt. π
std::set<move_only_type> s;
s.emplace(...);
move_only_type mot = std::move(s.extract(s.begin()).value());
see how that works? you extract the node handle, then .value() gives you the move-only object, and you std::move it out. chef's kiss. π
β FEATURE-TEST MACRO β
here's the feature-test macro table, and yes, I'm including every single detail because bestie, we don't skip:
| Feature-test macro | Value | Std | Feature |
|---|---|---|---|
__cpp_lib_associative_heterogeneous_erasure | 202110L | (C++23) | Heterogeneous erasure in associative containers and unordered associative containers, (3) |
that macro is long, but it's valid and it's doing its job. π«Ά
π¦ EXAMPLE π¦
okay so here's the full example, run it and watch the magic:
// Run this code
#include <algorithm>
#include <iostream>
#include <string_view>
#include <set>
void print(std::string_view comment, const auto& data)
{
std::cout << comment;
for (auto datum : data)
std::cout << ' ' << datum;
std::cout << '\n';
}
int main()
{
std::set<int> cont{1, 2, 3};
print("Start:", cont);
// Extract node handle and change key
auto nh = cont.extract(1);
nh.value() = 4;
print("After extract and before insert:", cont);
// Insert node handle back
cont.insert(std::move(nh));
print("End:", cont);
}
and the output is literally right here:
Start: 1 2 3
After extract and before insert: 2 3
End: 2 3 4
see how we yoinked 1, changed it to 4, and then slid it back in? that's the whole vibe. no elements were harmed (or copied, or moved) in the making of this example. iconic. π
πΈ SEE ALSO πΈ
mergeβ splices nodes from another container(C++17)(public member function). the social butterfly of node operations. π¦insertβ inserts elements or nodes(since C++17)(public member function). the classic. the reliable one. the one you already know and love. πeraseβ erases elements (public member function). not extract, just erase. know the difference bestie. π
and that's the whole page, bestie! no cap, you're now a std::set::extract expert. this manual page came from http://cppreference.com, version 2024.06.10, dated 2024.06.10, and honestly? it ate. π
β¨ππ¦πΈππ«Ά
periodt. π
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms