Files
cppdraft_translate/cppdraft/unord/set.md
2025-10-25 03:02:53 +03:00

224 lines
20 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[unord.set]
# 23 Containers library [[containers]](./#containers)
## 23.5 Unordered associative containers [[unord]](unord#set)
### 23.5.6 Class template unordered_set [unord.set]
#### [23.5.6.1](#overview) Overview [[unord.set.overview]](unord.set.overview)
[1](#overview-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L14691)
An unordered_set is an unordered associative container that
supports unique keys (an unordered_set contains at most one of each
key value) and in which the elements' keys are the elements
themselves[.](#overview-1.sentence-1)
The unordered_set class
supports forward iterators[.](#overview-1.sentence-2)
[2](#overview-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L14701)
An unordered_set meets all of the requirements
of a container ([[container.reqmts]](container.reqmts "23.2.2.2Container requirements")),
of an allocator-aware container ([[container.alloc.reqmts]](container.alloc.reqmts "23.2.2.5Allocator-aware containers")), and
of an unordered associative container ([[unord.req]](unord.req "23.2.8Unordered associative containers"))[.](#overview-2.sentence-1)
It provides the operations described in the preceding requirements table for unique keys;
that is, an unordered_set supports the a_uniq operations in that table,
not the a_eq operations[.](#overview-2.sentence-2)
For an unordered_set<Key> the key_type and the value_type are both Key[.](#overview-2.sentence-3)
The iterator and const_iterator types are both constant iterator types[.](#overview-2.sentence-4)
It is unspecified whether they are the same type[.](#overview-2.sentence-5)
[3](#overview-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L14714)
Subclause [unord.set] only describes operations on unordered_set that
are not described in one of the requirement tables, or for which there
is additional semantic information[.](#overview-3.sentence-1)
[4](#overview-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L14719)
The types iterator and const_iterator meet
the constexpr iterator requirements ([[iterator.requirements.general]](iterator.requirements.general "24.3.1General"))[.](#overview-4.sentence-1)
[🔗](#lib:unordered_set_)
namespace std {template<class Key, class Hash = hash<Key>, class Pred = equal_to<Key>, class Allocator = allocator<Key>>class unordered_set {public:// typesusing key_type = Key; using value_type = Key; using hasher = Hash; using key_equal = Pred; using allocator_type = Allocator; using pointer = typename allocator_traits<Allocator>::pointer; using const_pointer = typename allocator_traits<Allocator>::const_pointer; using reference = value_type&; using const_reference = const value_type&; using size_type = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2Requirements")using difference_type = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2Requirements")using iterator = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2Requirements")using const_iterator = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2Requirements")using local_iterator = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2Requirements")using const_local_iterator = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2Requirements")using node_type = *unspecified*; using insert_return_type = *insert-return-type*<iterator, node_type>; // [[unord.set.cnstr]](#cnstr "23.5.6.2Constructors"), construct/copy/destroyconstexpr unordered_set(); constexpr explicit unordered_set(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); template<class InputIterator>constexpr unordered_set(InputIterator f, InputIterator l,
size_type n = *see below*, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R>constexpr unordered_set(from_range_t, R&& rg,
size_type n = *see below*, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); constexpr unordered_set(const unordered_set&); constexpr unordered_set(unordered_set&&); constexpr explicit unordered_set(const Allocator&); constexpr unordered_set(const unordered_set&, const type_identity_t<Allocator>&); constexpr unordered_set(unordered_set&&, const type_identity_t<Allocator>&); constexpr unordered_set(initializer_list<value_type> il,
size_type n = *see below*, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); constexpr unordered_set(size_type n, const allocator_type& a): unordered_set(n, hasher(), key_equal(), a) { }constexpr unordered_set(size_type n, const hasher& hf, const allocator_type& a): unordered_set(n, hf, key_equal(), a) { }template<class InputIterator>constexpr unordered_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a): unordered_set(f, l, n, hasher(), key_equal(), a) { }template<class InputIterator>constexpr unordered_set(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a): unordered_set(f, l, n, hf, key_equal(), a) { }constexpr unordered_set(initializer_list<value_type> il, size_type n, const allocator_type& a): unordered_set(il, n, hasher(), key_equal(), a) { }template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R>constexpr unordered_set(from_range_t, R&& rg, size_type n, const allocator_type& a): unordered_set(from_range, std::forward<R>(rg), n, hasher(), key_equal(), a) { }template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R>constexpr unordered_set(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a): unordered_set(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { }constexpr unordered_set(initializer_list<value_type> il, size_type n, const hasher& hf, const allocator_type& a): unordered_set(il, n, hf, key_equal(), a) { }constexpr ~unordered_set(); constexpr unordered_set& operator=(const unordered_set&); constexpr unordered_set& operator=(unordered_set&&)noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_move_assignable_v<Hash> && is_nothrow_move_assignable_v<Pred>); constexpr unordered_set& operator=(initializer_list<value_type>); constexpr allocator_type get_allocator() const noexcept; // iteratorsconstexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept; constexpr iterator end() noexcept; constexpr const_iterator end() const noexcept; constexpr const_iterator cbegin() const noexcept; constexpr const_iterator cend() const noexcept; // capacityconstexpr bool empty() const noexcept; constexpr size_type size() const noexcept; constexpr size_type max_size() const noexcept; // [[unord.set.modifiers]](#modifiers "23.5.6.4Modifiers"), modifierstemplate<class... Args> constexpr pair<iterator, bool> emplace(Args&&... args); template<class... Args>constexpr iterator emplace_hint(const_iterator position, Args&&... args); constexpr pair<iterator, bool> insert(const value_type& obj); constexpr pair<iterator, bool> insert(value_type&& obj); template<class K> constexpr pair<iterator, bool> insert(K&& obj); constexpr iterator insert(const_iterator hint, const value_type& obj); constexpr iterator insert(const_iterator hint, value_type&& obj); template<class K> constexpr iterator insert(const_iterator hint, K&& obj); template<class InputIterator> constexpr void insert(InputIterator first, InputIterator last); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R>constexpr void insert_range(R&& rg); constexpr void insert(initializer_list<value_type>); constexpr node_type extract(const_iterator position); constexpr node_type extract(const key_type& x); template<class K> constexpr node_type extract(K&& x); constexpr insert_return_type insert(node_type&& nh); constexpr iterator insert(const_iterator hint, node_type&& nh); constexpr iterator erase(iterator position)requires (![same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<iterator, const_iterator>); constexpr iterator erase(const_iterator position); constexpr size_type erase(const key_type& k); template<class K> constexpr size_type erase(K&& x); constexpr iterator erase(const_iterator first, const_iterator last); constexpr void swap(unordered_set&)noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_swappable_v<Hash> && is_nothrow_swappable_v<Pred>); constexpr void clear() noexcept; template<class H2, class P2>constexpr void merge(unordered_set<Key, H2, P2, Allocator>& source); template<class H2, class P2>constexpr void merge(unordered_set<Key, H2, P2, Allocator>&& source); template<class H2, class P2>constexpr void merge(unordered_multiset<Key, H2, P2, Allocator>& source); template<class H2, class P2>constexpr void merge(unordered_multiset<Key, H2, P2, Allocator>&& source); // observersconstexpr hasher hash_function() const; constexpr key_equal key_eq() const; // set operationsconstexpr iterator find(const key_type& k); constexpr const_iterator find(const key_type& k) const; template<class K>constexpr iterator find(const K& k); template<class K>constexpr const_iterator find(const K& k) const; constexpr size_type count(const key_type& k) const; template<class K>constexpr size_type count(const K& k) const; constexpr bool contains(const key_type& k) const; template<class K>constexpr bool contains(const K& k) const; constexpr pair<iterator, iterator> equal_range(const key_type& k); constexpr pair<const_iterator, const_iterator> equal_range(const key_type& k) const; template<class K>constexpr pair<iterator, iterator> equal_range(const K& k); template<class K>constexpr pair<const_iterator, const_iterator> equal_range(const K& k) const; // bucket interfaceconstexpr size_type bucket_count() const noexcept; constexpr size_type max_bucket_count() const noexcept; constexpr size_type bucket_size(size_type n) const; constexpr size_type bucket(const key_type& k) const; template<class K> constexpr size_type bucket(const K& k) const; constexpr local_iterator begin(size_type n); constexpr const_local_iterator begin(size_type n) const; constexpr local_iterator end(size_type n); constexpr const_local_iterator end(size_type n) const; constexpr const_local_iterator cbegin(size_type n) const; constexpr const_local_iterator cend(size_type n) const; // hash policyconstexpr float load_factor() const noexcept; constexpr float max_load_factor() const noexcept; constexpr void max_load_factor(float z); constexpr void rehash(size_type n); constexpr void reserve(size_type n); }; template<class InputIterator, class Hash = hash<*iter-value-type*<InputIterator>>, class Pred = equal_to<*iter-value-type*<InputIterator>>, class Allocator = allocator<*iter-value-type*<InputIterator>>> unordered_set(InputIterator, InputIterator, typename *see below*::size_type = *see below*,
Hash = Hash(), Pred = Pred(), Allocator = Allocator())-> unordered_set<*iter-value-type*<InputIterator>,
Hash, Pred, Allocator>; template<ranges::[input_range](range.refinements#concept:input_range "25.4.6Other range refinements[range.refinements]") R, class Hash = hash<ranges::range_value_t<R>>, class Pred = equal_to<ranges::range_value_t<R>>, class Allocator = allocator<ranges::range_value_t<R>>> unordered_set(from_range_t, R&&, typename *see below*::size_type = *see below*,
Hash = Hash(), Pred = Pred(), Allocator = Allocator())-> unordered_set<ranges::range_value_t<R>, Hash, Pred, Allocator>; template<class T, class Hash = hash<T>, class Pred = equal_to<T>, class Allocator = allocator<T>> unordered_set(initializer_list<T>, typename *see below*::size_type = *see below*,
Hash = Hash(), Pred = Pred(), Allocator = Allocator())-> unordered_set<T, Hash, Pred, Allocator>; template<class InputIterator, class Allocator> unordered_set(InputIterator, InputIterator, typename *see below*::size_type, Allocator)-> unordered_set<*iter-value-type*<InputIterator>,
hash<*iter-value-type*<InputIterator>>,
equal_to<*iter-value-type*<InputIterator>>,
Allocator>; template<class InputIterator, class Hash, class Allocator> unordered_set(InputIterator, InputIterator, typename *see below*::size_type,
Hash, Allocator)-> unordered_set<*iter-value-type*<InputIterator>, Hash,
equal_to<*iter-value-type*<InputIterator>>,
Allocator>; template<ranges::[input_range](range.refinements#concept:input_range "25.4.6Other range refinements[range.refinements]") R, class Allocator> unordered_set(from_range_t, R&&, typename *see below*::size_type, Allocator)-> unordered_set<ranges::range_value_t<R>, hash<ranges::range_value_t<R>>,
equal_to<ranges::range_value_t<R>>, Allocator>; template<ranges::[input_range](range.refinements#concept:input_range "25.4.6Other range refinements[range.refinements]") R, class Allocator> unordered_set(from_range_t, R&&, Allocator)-> unordered_set<ranges::range_value_t<R>, hash<ranges::range_value_t<R>>,
equal_to<ranges::range_value_t<R>>, Allocator>; template<ranges::[input_range](range.refinements#concept:input_range "25.4.6Other range refinements[range.refinements]") R, class Hash, class Allocator> unordered_set(from_range_t, R&&, typename *see below*::size_type, Hash, Allocator)-> unordered_set<ranges::range_value_t<R>, Hash,
equal_to<ranges::range_value_t<R>>, Allocator>; template<class T, class Allocator> unordered_set(initializer_list<T>, typename *see below*::size_type, Allocator)-> unordered_set<T, hash<T>, equal_to<T>, Allocator>; template<class T, class Hash, class Allocator> unordered_set(initializer_list<T>, typename *see below*::size_type, Hash, Allocator)-> unordered_set<T, Hash, equal_to<T>, Allocator>;}
[5](#overview-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L14970)
A size_type parameter type in an unordered_set deduction guide
refers to the size_type member type of
the type deduced by the deduction guide[.](#overview-5.sentence-1)
#### [23.5.6.2](#cnstr) Constructors [[unord.set.cnstr]](unord.set.cnstr)
[🔗](#lib:unordered_set,constructor)
`constexpr unordered_set() : unordered_set(size_type(see below)) { }
constexpr explicit unordered_set(size_type n, const hasher& hf = hasher(),
const key_equal& eql = key_equal(),
const allocator_type& a = allocator_type());
`
[1](#cnstr-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L14986)
*Effects*: Constructs an empty unordered_set using the
specified hash function, key equality predicate, and allocator, and
using at least n buckets[.](#cnstr-1.sentence-1)
For the default constructor,
the number of buckets is implementation-defined[.](#cnstr-1.sentence-2)
max_load_factor() returns 1.0[.](#cnstr-1.sentence-3)
[2](#cnstr-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L14995)
*Complexity*: Constant[.](#cnstr-2.sentence-1)
[🔗](#lib:unordered_set,constructor_)
`template<class InputIterator>
constexpr unordered_set(InputIterator f, InputIterator l,
size_type n = see below, const hasher& hf = hasher(),
const key_equal& eql = key_equal(),
const allocator_type& a = allocator_type());
template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R>
constexpr unordered_multiset(from_range_t, R&& rg,
size_type n = see below, const hasher& hf = hasher(),
const key_equal& eql = key_equal(),
const allocator_type& a = allocator_type());
constexpr unordered_set(initializer_list<value_type> il,
size_type n = see below, const hasher& hf = hasher(),
const key_equal& eql = key_equal(),
const allocator_type& a = allocator_type());
`
[3](#cnstr-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L15019)
*Effects*: Constructs an empty unordered_set using the
specified hash function, key equality predicate, and allocator, and
using at least n buckets[.](#cnstr-3.sentence-1)
If n is not
provided, the number of buckets is implementation-defined[.](#cnstr-3.sentence-2)
Then
inserts elements from the range [f, l), rg, or il,
respectively[.](#cnstr-3.sentence-3)
max_load_factor() returns 1.0[.](#cnstr-3.sentence-4)
[4](#cnstr-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L15030)
*Complexity*: Average case linear, worst case quadratic[.](#cnstr-4.sentence-1)
#### [23.5.6.3](#erasure) Erasure [[unord.set.erasure]](unord.set.erasure)
[🔗](#lib:erase_if,unordered_set)
`template<class K, class H, class P, class A, class Predicate>
constexpr typename unordered_set<K, H, P, A>::size_type
erase_if(unordered_set<K, H, P, A>& c, Predicate pred);
`
[1](#erasure-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L15045)
*Effects*: Equivalent to:auto original_size = c.size();for (auto i = c.begin(), last = c.end(); i != last; ) {if (pred(*i)) { i = c.erase(i); } else {++i; }}return original_size - c.size();
#### [23.5.6.4](#modifiers) Modifiers [[unord.set.modifiers]](unord.set.modifiers)
[🔗](#lib:insert,unordered_set)
`template<class K> constexpr pair<iterator, bool> insert(K&& obj);
template<class K> constexpr iterator insert(const_iterator hint, K&& obj);
`
[1](#modifiers-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L15070)
*Constraints*: The [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]")*s* Hash::is_transparent andPred::is_transparent are valid and denote types[.](#modifiers-1.sentence-1)
For the second overload,is_convertible_v<K&&, const_iterator> andis_convertible_v<K&&, iterator> are both false[.](#modifiers-1.sentence-2)
[2](#modifiers-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L15078)
*Preconditions*: value_type is *Cpp17EmplaceConstructible* into unordered_set from std::forward<K>
(obj)[.](#modifiers-2.sentence-1)
[3](#modifiers-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L15083)
*Effects*: If the set already contains an element that is equivalent to obj,
there is no effect[.](#modifiers-3.sentence-1)
Otherwise, let h be hash_function()(obj)[.](#modifiers-3.sentence-2)
Constructs an object u of type value_type with std::forward<K>(obj)[.](#modifiers-3.sentence-3)
If hash_function()(u) != h || contains(u) is true,
the behavior is undefined[.](#modifiers-3.sentence-4)
Inserts u into *this[.](#modifiers-3.sentence-5)
[4](#modifiers-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L15094)
*Returns*: For the first overload,
the bool component of the returned pair is true if and only if the insertion took place[.](#modifiers-4.sentence-1)
The returned iterator points to the set element
that is equivalent to obj[.](#modifiers-4.sentence-2)
[5](#modifiers-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L15102)
*Complexity*: Average case constant, worst case linear[.](#modifiers-5.sentence-1)