[unord] (original) (raw)
22 Containers library [containers]
22.5 Unordered associative containers [unord]
22.5.1 In general [unord.general]
The header <unordered_map> defines the class templatesunordered_map andunordered_multimap; the header <unordered_set> defines the class templatesunordered_set and unordered_multiset.
The exposition-only alias templatesiter-value-type, iter-key-type,iter-mapped-type, and iter-to-alloc-typedefined in [associative.general] may appear in deduction guides for unordered containers.
22.5.2 Header <unordered_map> synopsis [unord.map.syn]
#include
#include
namespace std {
template<class Key, class T, class Hash = hash, class Pred = equal_to, class Alloc = allocator<pair<const Key, T>>> class unordered_map;
template<class Key, class T, class Hash = hash, class Pred = equal_to, class Alloc = allocator<pair<const Key, T>>> class unordered_multimap;
template<class Key, class T, class Hash, class Pred, class Alloc> bool operator==(const unordered_map<Key, T, Hash, Pred, Alloc>& a, const unordered_map<Key, T, Hash, Pred, Alloc>& b);
template<class Key, class T, class Hash, class Pred, class Alloc> bool operator==(const unordered_multimap<Key, T, Hash, Pred, Alloc>& a, const unordered_multimap<Key, T, Hash, Pred, Alloc>& b);
template<class Key, class T, class Hash, class Pred, class Alloc> void swap(unordered_map<Key, T, Hash, Pred, Alloc>& x, unordered_map<Key, T, Hash, Pred, Alloc>& y) noexcept(noexcept(x.swap(y)));
template<class Key, class T, class Hash, class Pred, class Alloc> void swap(unordered_multimap<Key, T, Hash, Pred, Alloc>& x, unordered_multimap<Key, T, Hash, Pred, Alloc>& y) noexcept(noexcept(x.swap(y)));
template<class K, class T, class H, class P, class A, class Predicate> typename unordered_map<K, T, H, P, A>::size_type erase_if(unordered_map<K, T, H, P, A>& c, Predicate pred);
template<class K, class T, class H, class P, class A, class Predicate> typename unordered_multimap<K, T, H, P, A>::size_type erase_if(unordered_multimap<K, T, H, P, A>& c, Predicate pred);
namespace pmr { template<class Key, class T, class Hash = hash, class Pred = equal_to> using unordered_map = std::unordered_map<Key, T, Hash, Pred, polymorphic_allocator<pair<const Key, T>>>; template<class Key, class T, class Hash = hash, class Pred = equal_to> using unordered_multimap = std::unordered_multimap<Key, T, Hash, Pred, polymorphic_allocator<pair<const Key, T>>>;
} }
22.5.3 Header <unordered_set> synopsis [unord.set.syn]
#include
#include
namespace std {
template<class Key, class Hash = hash, class Pred = equal_to, class Alloc = allocator> class unordered_set;
template<class Key, class Hash = hash, class Pred = equal_to, class Alloc = allocator> class unordered_multiset;
template<class Key, class Hash, class Pred, class Alloc> bool operator==(const unordered_set<Key, Hash, Pred, Alloc>& a, const unordered_set<Key, Hash, Pred, Alloc>& b);
template<class Key, class Hash, class Pred, class Alloc> bool operator==(const unordered_multiset<Key, Hash, Pred, Alloc>& a, const unordered_multiset<Key, Hash, Pred, Alloc>& b);
template<class Key, class Hash, class Pred, class Alloc> void swap(unordered_set<Key, Hash, Pred, Alloc>& x, unordered_set<Key, Hash, Pred, Alloc>& y) noexcept(noexcept(x.swap(y)));
template<class Key, class Hash, class Pred, class Alloc> void swap(unordered_multiset<Key, Hash, Pred, Alloc>& x, unordered_multiset<Key, Hash, Pred, Alloc>& y) noexcept(noexcept(x.swap(y)));
template<class K, class H, class P, class A, class Predicate> typename unordered_set<K, H, P, A>::size_type erase_if(unordered_set<K, H, P, A>& c, Predicate pred);
template<class K, class H, class P, class A, class Predicate> typename unordered_multiset<K, H, P, A>::size_type erase_if(unordered_multiset<K, H, P, A>& c, Predicate pred);
namespace pmr { template<class Key, class Hash = hash, class Pred = equal_to> using unordered_set = std::unordered_set<Key, Hash, Pred, polymorphic_allocator>;
template<class Key,
class Hash = hash<Key>,
class Pred = equal_to<Key>>
using unordered_multiset = std::unordered_multiset<Key, Hash, Pred,
polymorphic_allocator<Key>>;} }
22.5.4 Class template unordered_map [unord.map]
22.5.4.1 Overview [unord.map.overview]
An unordered_map is an unordered associative container that supports unique keys (an unordered_map contains at most one of each key value) and that associates values of another typemapped_type with the keys.
The unordered_map class supports forward iterators.
An unordered_map meets all of the requirements of a container, of an unordered associative container, and of an allocator-aware container (Table 76).
It provides the operations described in the preceding requirements table for unique keys; that is, an unordered_map supports the a_uniq operations in that table, not the a_eq operations.
For an unordered_map<Key, T> the key type is Key, the mapped type is T, and the value type is pair<const Key, T>.
Subclause [unord.map] only describes operations on unordered_map that are not described in one of the requirement tables, or for which there is additional semantic information.
namespace std { template<class Key, class T, class Hash = hash, class Pred = equal_to, class Allocator = allocator<pair<const Key, T>>> class unordered_map { public:
using key_type = Key;
using mapped_type = T;
using value_type = pair<const Key, T>;
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;
using difference_type = implementation-defined;
using iterator = implementation-defined;
using const_iterator = implementation-defined;
using local_iterator = implementation-defined;
using const_local_iterator = implementation-defined;
using node_type = unspecified;
using insert_return_type = insert-return-type<iterator, node_type>;
unordered_map();
explicit unordered_map(size_type n,
const hasher& hf = hasher(),
const key_equal& eql = key_equal(),
const allocator_type& a = allocator_type());
template<class InputIterator>
unordered_map(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());
unordered_map(const unordered_map&);
unordered_map(unordered_map&&);
explicit unordered_map(const Allocator&);
unordered_map(const unordered_map&, const Allocator&);
unordered_map(unordered_map&&, const Allocator&);
unordered_map(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());
unordered_map(size_type n, const allocator_type& a)
: unordered_map(n, hasher(), key_equal(), a) { }
unordered_map(size_type n, const hasher& hf, const allocator_type& a)
: unordered_map(n, hf, key_equal(), a) { }
template<class InputIterator>
unordered_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
: unordered_map(f, l, n, hasher(), key_equal(), a) { }
template<class InputIterator>
unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf,
const allocator_type& a)
: unordered_map(f, l, n, hf, key_equal(), a) { }
unordered_map(initializer_list<value_type> il, size_type n, const allocator_type& a)
: unordered_map(il, n, hasher(), key_equal(), a) { }
unordered_map(initializer_list<value_type> il, size_type n, const hasher& hf,
const allocator_type& a)
: unordered_map(il, n, hf, key_equal(), a) { }
~unordered_map();
unordered_map& operator=(const unordered_map&);
unordered_map& operator=(unordered_map&&)
noexcept(allocator_traits<Allocator>::is_always_equal::value &&
is_nothrow_move_assignable_v<Hash> &&
is_nothrow_move_assignable_v<Pred>);
unordered_map& operator=(initializer_list<value_type>);
allocator_type get_allocator() const noexcept;
iterator begin() noexcept;
const_iterator begin() const noexcept;
iterator end() noexcept;
const_iterator end() const noexcept;
const_iterator cbegin() const noexcept;
const_iterator cend() const noexcept;
[[nodiscard]] bool empty() const noexcept;
size_type size() const noexcept;
size_type max_size() const noexcept;
template<class... Args> pair<iterator, bool> emplace(Args&&... args);
template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
pair<iterator, bool> insert(const value_type& obj);
pair<iterator, bool> insert(value_type&& obj);
template<class P> pair<iterator, bool> insert(P&& obj);
iterator insert(const_iterator hint, const value_type& obj);
iterator insert(const_iterator hint, value_type&& obj);
template<class P> iterator insert(const_iterator hint, P&& obj);
template<class InputIterator> void insert(InputIterator first, InputIterator last);
void insert(initializer_list<value_type>);
node_type extract(const_iterator position);
node_type extract(const key_type& x);
insert_return_type insert(node_type&& nh);
iterator insert(const_iterator hint, node_type&& nh);
template<class... Args>
pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
template<class... Args>
pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
template<class... Args>
iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
template<class... Args>
iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
template<class M>
pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
template<class M>
pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
template<class M>
iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
template<class M>
iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
iterator erase(iterator position);
iterator erase(const_iterator position);
size_type erase(const key_type& k);
iterator erase(const_iterator first, const_iterator last);
void swap(unordered_map&)
noexcept(allocator_traits<Allocator>::is_always_equal::value &&
is_nothrow_swappable_v<Hash> &&
is_nothrow_swappable_v<Pred>);
void clear() noexcept;
template<class H2, class P2>
void merge(unordered_map<Key, T, H2, P2, Allocator>& source);
template<class H2, class P2>
void merge(unordered_map<Key, T, H2, P2, Allocator>&& source);
template<class H2, class P2>
void merge(unordered_multimap<Key, T, H2, P2, Allocator>& source);
template<class H2, class P2>
void merge(unordered_multimap<Key, T, H2, P2, Allocator>&& source);
hasher hash_function() const;
key_equal key_eq() const;
iterator find(const key_type& k);
const_iterator find(const key_type& k) const;
template<class K>
iterator find(const K& k);
template<class K>
const_iterator find(const K& k) const;
template<class K>
size_type count(const key_type& k) const;
template<class K>
size_type count(const K& k) const;
bool contains(const key_type& k) const;
template<class K>
bool contains(const K& k) const;
pair<iterator, iterator> equal_range(const key_type& k);
pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
template<class K>
pair<iterator, iterator> equal_range(const K& k);
template<class K>
pair<const_iterator, const_iterator> equal_range(const K& k) const;
mapped_type& operator[](const key_type& k);
mapped_type& operator[](key_type&& k);
mapped_type& at(const key_type& k);
const mapped_type& at(const key_type& k) const;
size_type bucket_count() const noexcept;
size_type max_bucket_count() const noexcept;
size_type bucket_size(size_type n) const;
size_type bucket(const key_type& k) const;
local_iterator begin(size_type n);
const_local_iterator begin(size_type n) const;
local_iterator end(size_type n);
const_local_iterator end(size_type n) const;
const_local_iterator cbegin(size_type n) const;
const_local_iterator cend(size_type n) const;
float load_factor() const noexcept;
float max_load_factor() const noexcept;
void max_load_factor(float z);
void rehash(size_type n);
void reserve(size_type n);};
template<class InputIterator, class Hash = hash<iter-key-type>, class Pred = equal_to<iter-key-type>, class Allocator = allocator<iter-to-alloc-type>> unordered_map(InputIterator, InputIterator, typename see below::size_type = see below, Hash = Hash(), Pred = Pred(), Allocator = Allocator()) -> unordered_map<iter-key-type, iter-mapped-type, Hash, Pred, Allocator>;
template<class Key, class T, class Hash = hash, class Pred = equal_to, class Allocator = allocator<pair<const Key, T>>> unordered_map(initializer_list<pair<Key, T>>, typename see below::size_type = see below, Hash = Hash(), Pred = Pred(), Allocator = Allocator()) -> unordered_map<Key, T, Hash, Pred, Allocator>;
template<class InputIterator, class Allocator> unordered_map(InputIterator, InputIterator, typename see below::size_type, Allocator) -> unordered_map<iter-key-type, iter-mapped-type, hash<iter-key-type>, equal_to<iter-key-type>, Allocator>;
template<class InputIterator, class Allocator> unordered_map(InputIterator, InputIterator, Allocator) -> unordered_map<iter-key-type, iter-mapped-type, hash<iter-key-type>, equal_to<iter-key-type>, Allocator>;
template<class InputIterator, class Hash, class Allocator> unordered_map(InputIterator, InputIterator, typename see below::size_type, Hash, Allocator) -> unordered_map<iter-key-type, iter-mapped-type, Hash, equal_to<iter-key-type>, Allocator>;
template<class Key, class T, class Allocator> unordered_map(initializer_list<pair<Key, T>>, typename see below::size_type, Allocator) -> unordered_map<Key, T, hash, equal_to, Allocator>;
template<class Key, class T, class Allocator> unordered_map(initializer_list<pair<Key, T>>, Allocator) -> unordered_map<Key, T, hash, equal_to, Allocator>;
template<class Key, class T, class Hash, class Allocator> unordered_map(initializer_list<pair<Key, T>>, typename see below::size_type, Hash, Allocator) -> unordered_map<Key, T, Hash, equal_to, Allocator>;
template<class Key, class T, class Hash, class Pred, class Alloc> void swap(unordered_map<Key, T, Hash, Pred, Alloc>& x, unordered_map<Key, T, Hash, Pred, Alloc>& y) noexcept(noexcept(x.swap(y))); }
A size_type parameter type in an unordered_map deduction guide refers to the size_type member type of the type deduced by the deduction guide.
22.5.4.2 Constructors [unord.map.cnstr]
unordered_map() : unordered_map(size_type(see below)) { } explicit unordered_map(size_type n,const hasher& hf = hasher(),const key_equal& eql = key_equal(),const allocator_type& a = allocator_type());
Effects:Constructs an empty unordered_map using the specified hash function, key equality predicate, and allocator, and using at least n buckets.
For the default constructor, the number of buckets is implementation-defined.
max_load_factor() returns 1.0.
template<class InputIterator> unordered_map(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()); unordered_map(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());
Effects:Constructs an empty unordered_map using the specified hash function, key equality predicate, and allocator, and using at least n buckets.
If n is not provided, the number of buckets is implementation-defined.
Then inserts elements from the range [f, l)for the first form, or from the range[il.begin(), il.end()) for the second form.
max_load_factor() returns 1.0.
Complexity:Average case linear, worst case quadratic.
22.5.4.3 Element access [unord.map.elem]
mapped_type& operator[](const key_type& k);
Effects:Equivalent to: return try_emplace(k).first->second;
mapped_type& operator[](key_type&& k);
Effects:Equivalent to: return try_emplace(move(k)).first->second;
mapped_type& at(const key_type& k);const mapped_type& at(const key_type& k) const;
Returns:A reference to x.second, where x is the (unique) element whose key is equivalent to k.
Throws:An exception object of type out_of_range if no such element is present.
22.5.4.4 Modifiers [unord.map.modifiers]
template<class P> pair<iterator, bool> insert(P&& obj);
Constraints: is_constructible_v<value_type, P&&> is true.
Effects:Equivalent to: return emplace(std::forward<P>(obj));
template<class P> iterator insert(const_iterator hint, P&& obj);
Constraints: is_constructible_v<value_type, P&&> is true.
Effects:Equivalent to:return emplace_hint(hint, std::forward<P>(obj));
template<class... Args> pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);template<class... Args> iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
Preconditions: value_type is Cpp17EmplaceConstructible into unordered_mapfrom piecewise_construct, forward_as_tuple(k),forward_as_tuple(std::forward<Args>(args)...).
Effects:If the map already contains an element whose key is equivalent to k, there is no effect.
Otherwise inserts an object of type value_typeconstructed with piecewise_construct, forward_as_tuple(k),forward_as_tuple(std::forward<Args>(args)...).
Returns:In the first overload, the bool component of the returned pair is trueif and only if the insertion took place.
The returned iterator points to the map element whose key is equivalent to k.
Complexity:The same as emplace and emplace_hint, respectively.
template<class... Args> pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);template<class... Args> iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
Preconditions: value_type is Cpp17EmplaceConstructible into unordered_mapfrom piecewise_construct, forward_as_tuple(std::move(k)),forward_as_tuple(std::forward<Args>(args)...).
Effects:If the map already contains an element whose key is equivalent to k, there is no effect.
Otherwise inserts an object of type value_typeconstructed with piecewise_construct, forward_as_tuple(std::move(k)),forward_as_tuple(std::forward<Args>(args)...).
Returns:In the first overload, the bool component of the returned pair is trueif and only if the insertion took place.
The returned iterator points to the map element whose key is equivalent to k.
Complexity:The same as emplace and emplace_hint, respectively.
template<class M> pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);template<class M> iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
Mandates: is_assignable_v<mapped_type&, M&&> is true.
Preconditions: value_type is Cpp17EmplaceConstructible into unordered_mapfrom k, std::forward<M>(obj).
Effects:If the map already contains an element ewhose key is equivalent to k, assigns std::forward<M>(obj) to e.second.
Otherwise inserts an object of type value_typeconstructed with k, std::forward<M>(obj).
Returns:In the first overload, the bool component of the returned pair is trueif and only if the insertion took place.
The returned iterator points to the map element whose key is equivalent to k.
Complexity:The same as emplace and emplace_hint, respectively.
template<class M> pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);template<class M> iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
Mandates: is_assignable_v<mapped_type&, M&&> is true.
Preconditions: value_type is Cpp17EmplaceConstructible into unordered_mapfrom std::move(k), std::forward<M>(obj).
Effects:If the map already contains an element ewhose key is equivalent to k, assigns std::forward<M>(obj) to e.second.
Otherwise inserts an object of type value_typeconstructed with std::move(k), std::forward<M>(obj).
Returns:In the first overload, the bool component of the returned pair is trueif and only if the insertion took place.
The returned iterator points to the map element whose key is equivalent to k.
Complexity:The same as emplace and emplace_hint, respectively.
22.5.4.5 Erasure [unord.map.erasure]
template<class K, class T, class H, class P, class A, class Predicate> typename unordered_map<K, T, H, P, A>::size_type erase_if(unordered_map<K, T, H, P, A>& c, Predicate pred);
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();
22.5.5 Class template unordered_multimap [unord.multimap]
22.5.5.1 Overview [unord.multimap.overview]
An unordered_multimap is an unordered associative container that supports equivalent keys (an instance of unordered_multimap may contain multiple copies of each key value) and that associates values of another type mapped_type with the keys.
The unordered_multimap class supports forward iterators.
An unordered_multimap meets all of the requirements of a container, of an unordered associative container, and of an allocator-aware container (Table 76).
It provides the operations described in the preceding requirements table for equivalent keys; that is, an unordered_multimapsupports the a_eq operations in that table, not the a_uniq operations.
For an unordered_multimap<Key, T> the key type is Key, the mapped type is T, and the value type is pair<const Key, T>.
Subclause [unord.multimap] only describes operations on unordered_multimapthat are not described in one of the requirement tables, or for which there is additional semantic information.
namespace std { template<class Key, class T, class Hash = hash, class Pred = equal_to, class Allocator = allocator<pair<const Key, T>>> class unordered_multimap { public:
using key_type = Key;
using mapped_type = T;
using value_type = pair<const Key, T>;
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;
using difference_type = implementation-defined;
using iterator = implementation-defined;
using const_iterator = implementation-defined;
using local_iterator = implementation-defined;
using const_local_iterator = implementation-defined;
using node_type = unspecified;
unordered_multimap();
explicit unordered_multimap(size_type n,
const hasher& hf = hasher(),
const key_equal& eql = key_equal(),
const allocator_type& a = allocator_type());
template<class InputIterator>
unordered_multimap(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());
unordered_multimap(const unordered_multimap&);
unordered_multimap(unordered_multimap&&);
explicit unordered_multimap(const Allocator&);
unordered_multimap(const unordered_multimap&, const Allocator&);
unordered_multimap(unordered_multimap&&, const Allocator&);
unordered_multimap(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());
unordered_multimap(size_type n, const allocator_type& a)
: unordered_multimap(n, hasher(), key_equal(), a) { }
unordered_multimap(size_type n, const hasher& hf, const allocator_type& a)
: unordered_multimap(n, hf, key_equal(), a) { }
template<class InputIterator>
unordered_multimap(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
: unordered_multimap(f, l, n, hasher(), key_equal(), a) { }
template<class InputIterator>
unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf,
const allocator_type& a)
: unordered_multimap(f, l, n, hf, key_equal(), a) { }
unordered_multimap(initializer_list<value_type> il, size_type n, const allocator_type& a)
: unordered_multimap(il, n, hasher(), key_equal(), a) { }
unordered_multimap(initializer_list<value_type> il, size_type n, const hasher& hf,
const allocator_type& a)
: unordered_multimap(il, n, hf, key_equal(), a) { }
~unordered_multimap();
unordered_multimap& operator=(const unordered_multimap&);
unordered_multimap& operator=(unordered_multimap&&)
noexcept(allocator_traits<Allocator>::is_always_equal::value &&
is_nothrow_move_assignable_v<Hash> &&
is_nothrow_move_assignable_v<Pred>);
unordered_multimap& operator=(initializer_list<value_type>);
allocator_type get_allocator() const noexcept;
iterator begin() noexcept;
const_iterator begin() const noexcept;
iterator end() noexcept;
const_iterator end() const noexcept;
const_iterator cbegin() const noexcept;
const_iterator cend() const noexcept;
[[nodiscard]] bool empty() const noexcept;
size_type size() const noexcept;
size_type max_size() const noexcept;
template<class... Args> iterator emplace(Args&&... args);
template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
iterator insert(const value_type& obj);
iterator insert(value_type&& obj);
template<class P> iterator insert(P&& obj);
iterator insert(const_iterator hint, const value_type& obj);
iterator insert(const_iterator hint, value_type&& obj);
template<class P> iterator insert(const_iterator hint, P&& obj);
template<class InputIterator> void insert(InputIterator first, InputIterator last);
void insert(initializer_list<value_type>);
node_type extract(const_iterator position);
node_type extract(const key_type& x);
iterator insert(node_type&& nh);
iterator insert(const_iterator hint, node_type&& nh);
iterator erase(iterator position);
iterator erase(const_iterator position);
size_type erase(const key_type& k);
iterator erase(const_iterator first, const_iterator last);
void swap(unordered_multimap&)
noexcept(allocator_traits<Allocator>::is_always_equal::value &&
is_nothrow_swappable_v<Hash> &&
is_nothrow_swappable_v<Pred>);
void clear() noexcept;
template<class H2, class P2>
void merge(unordered_multimap<Key, T, H2, P2, Allocator>& source);
template<class H2, class P2>
void merge(unordered_multimap<Key, T, H2, P2, Allocator>&& source);
template<class H2, class P2>
void merge(unordered_map<Key, T, H2, P2, Allocator>& source);
template<class H2, class P2>
void merge(unordered_map<Key, T, H2, P2, Allocator>&& source);
hasher hash_function() const;
key_equal key_eq() const;
iterator find(const key_type& k);
const_iterator find(const key_type& k) const;
template<class K>
iterator find(const K& k);
template<class K>
const_iterator find(const K& k) const;
size_type count(const key_type& k) const;
template<class K>
size_type count(const K& k) const;
bool contains(const key_type& k) const;
template<class K>
bool contains(const K& k) const;
pair<iterator, iterator> equal_range(const key_type& k);
pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
template<class K>
pair<iterator, iterator> equal_range(const K& k);
template<class K>
pair<const_iterator, const_iterator> equal_range(const K& k) const;
size_type bucket_count() const noexcept;
size_type max_bucket_count() const noexcept;
size_type bucket_size(size_type n) const;
size_type bucket(const key_type& k) const;
local_iterator begin(size_type n);
const_local_iterator begin(size_type n) const;
local_iterator end(size_type n);
const_local_iterator end(size_type n) const;
const_local_iterator cbegin(size_type n) const;
const_local_iterator cend(size_type n) const;
float load_factor() const noexcept;
float max_load_factor() const noexcept;
void max_load_factor(float z);
void rehash(size_type n);
void reserve(size_type n);};
template<class InputIterator, class Hash = hash<iter-key-type>, class Pred = equal_to<iter-key-type>, class Allocator = allocator<iter-to-alloc-type>> unordered_multimap(InputIterator, InputIterator, typename see below::size_type = see below, Hash = Hash(), Pred = Pred(), Allocator = Allocator()) -> unordered_multimap<iter-key-type, iter-mapped-type, Hash, Pred, Allocator>;
template<class Key, class T, class Hash = hash, class Pred = equal_to, class Allocator = allocator<pair<const Key, T>>> unordered_multimap(initializer_list<pair<Key, T>>, typename see below::size_type = see below, Hash = Hash(), Pred = Pred(), Allocator = Allocator()) -> unordered_multimap<Key, T, Hash, Pred, Allocator>;
template<class InputIterator, class Allocator> unordered_multimap(InputIterator, InputIterator, typename see below::size_type, Allocator) -> unordered_multimap<iter-key-type, iter-mapped-type, hash<iter-key-type>, equal_to<iter-key-type>, Allocator>;
template<class InputIterator, class Allocator> unordered_multimap(InputIterator, InputIterator, Allocator) -> unordered_multimap<iter-key-type, iter-mapped-type, hash<iter-key-type>, equal_to<iter-key-type>, Allocator>;
template<class InputIterator, class Hash, class Allocator> unordered_multimap(InputIterator, InputIterator, typename see below::size_type, Hash, Allocator) -> unordered_multimap<iter-key-type, iter-mapped-type, Hash, equal_to<iter-key-type>, Allocator>;
template<class Key, class T, class Allocator> unordered_multimap(initializer_list<pair<Key, T>>, typename see below::size_type, Allocator) -> unordered_multimap<Key, T, hash, equal_to, Allocator>;
template<class Key, class T, class Allocator> unordered_multimap(initializer_list<pair<Key, T>>, Allocator) -> unordered_multimap<Key, T, hash, equal_to, Allocator>;
template<class Key, class T, class Hash, class Allocator> unordered_multimap(initializer_list<pair<Key, T>>, typename see below::size_type, Hash, Allocator) -> unordered_multimap<Key, T, Hash, equal_to, Allocator>;
template<class Key, class T, class Hash, class Pred, class Alloc> void swap(unordered_multimap<Key, T, Hash, Pred, Alloc>& x, unordered_multimap<Key, T, Hash, Pred, Alloc>& y) noexcept(noexcept(x.swap(y))); }
A size_type parameter type in an unordered_multimap deduction guide refers to the size_type member type of the type deduced by the deduction guide.
22.5.5.2 Constructors [unord.multimap.cnstr]
unordered_multimap() : unordered_multimap(size_type(see below)) { } explicit unordered_multimap(size_type n,const hasher& hf = hasher(),const key_equal& eql = key_equal(),const allocator_type& a = allocator_type());
Effects:Constructs an empty unordered_multimap using the specified hash function, key equality predicate, and allocator, and using at least n buckets.
For the default constructor, the number of buckets is implementation-defined.
max_load_factor() returns 1.0.
template<class InputIterator> unordered_multimap(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()); unordered_multimap(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());
Effects:Constructs an empty unordered_multimap using the specified hash function, key equality predicate, and allocator, and using at least n buckets.
If n is not provided, the number of buckets is implementation-defined.
Then inserts elements from the range [f, l)for the first form, or from the range[il.begin(), il.end()) for the second form.
max_load_factor() returns 1.0.
Complexity:Average case linear, worst case quadratic.
22.5.5.3 Modifiers [unord.multimap.modifiers]
template<class P> iterator insert(P&& obj);
Constraints: is_constructible_v<value_type, P&&> is true.
Effects:Equivalent to: return emplace(std::forward<P>(obj));
template<class P> iterator insert(const_iterator hint, P&& obj);
Constraints: is_constructible_v<value_type, P&&> is true.
Effects:Equivalent to:return emplace_hint(hint, std::forward<P>(obj));
22.5.5.4 Erasure [unord.multimap.erasure]
template<class K, class T, class H, class P, class A, class Predicate> typename unordered_multimap<K, T, H, P, A>::size_type erase_if(unordered_multimap<K, T, H, P, A>& c, Predicate pred);
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();
22.5.6 Class template unordered_set [unord.set]
22.5.6.1 Overview [unord.set.overview]
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.
The unordered_set class supports forward iterators.
An unordered_set meets all of the requirements of a container, of an unordered associative container, and of an allocator-aware container (Table 76).
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.
For an unordered_set<Key> the key type and the value type are both Key.
The iterator and const_iterator types are both constant iterator types.
It is unspecified whether they are the same type.
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.
namespace std { template<class Key, class Hash = hash, class Pred = equal_to, class Allocator = allocator> class unordered_set { public:
using 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;
using difference_type = implementation-defined;
using iterator = implementation-defined;
using const_iterator = implementation-defined;
using local_iterator = implementation-defined;
using const_local_iterator = implementation-defined;
using node_type = unspecified;
using insert_return_type = insert-return-type<iterator, node_type>;
unordered_set();
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>
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());
unordered_set(const unordered_set&);
unordered_set(unordered_set&&);
explicit unordered_set(const Allocator&);
unordered_set(const unordered_set&, const Allocator&);
unordered_set(unordered_set&&, const Allocator&);
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());
unordered_set(size_type n, const allocator_type& a)
: unordered_set(n, hasher(), key_equal(), a) { }
unordered_set(size_type n, const hasher& hf, const allocator_type& a)
: unordered_set(n, hf, key_equal(), a) { }
template<class InputIterator>
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>
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) { }
unordered_set(initializer_list<value_type> il, size_type n, const allocator_type& a)
: unordered_set(il, n, hasher(), key_equal(), a) { }
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) { }
~unordered_set();
unordered_set& operator=(const unordered_set&);
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>);
unordered_set& operator=(initializer_list<value_type>);
allocator_type get_allocator() const noexcept;
iterator begin() noexcept;
const_iterator begin() const noexcept;
iterator end() noexcept;
const_iterator end() const noexcept;
const_iterator cbegin() const noexcept;
const_iterator cend() const noexcept;
[[nodiscard]] bool empty() const noexcept;
size_type size() const noexcept;
size_type max_size() const noexcept;
template<class... Args> pair<iterator, bool> emplace(Args&&... args);
template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
pair<iterator, bool> insert(const value_type& obj);
pair<iterator, bool> insert(value_type&& obj);
iterator insert(const_iterator hint, const value_type& obj);
iterator insert(const_iterator hint, value_type&& obj);
template<class InputIterator> void insert(InputIterator first, InputIterator last);
void insert(initializer_list<value_type>);
node_type extract(const_iterator position);
node_type extract(const key_type& x);
insert_return_type insert(node_type&& nh);
iterator insert(const_iterator hint, node_type&& nh);
iterator erase(iterator position);
iterator erase(const_iterator position);
size_type erase(const key_type& k);
iterator erase(const_iterator first, const_iterator last);
void swap(unordered_set&)
noexcept(allocator_traits<Allocator>::is_always_equal::value &&
is_nothrow_swappable_v<Hash> &&
is_nothrow_swappable_v<Pred>);
void clear() noexcept;
template<class H2, class P2>
void merge(unordered_set<Key, H2, P2, Allocator>& source);
template<class H2, class P2>
void merge(unordered_set<Key, H2, P2, Allocator>&& source);
template<class H2, class P2>
void merge(unordered_multiset<Key, H2, P2, Allocator>& source);
template<class H2, class P2>
void merge(unordered_multiset<Key, H2, P2, Allocator>&& source);
hasher hash_function() const;
key_equal key_eq() const;
iterator find(const key_type& k);
const_iterator find(const key_type& k) const;
template<class K>
iterator find(const K& k);
template<class K>
const_iterator find(const K& k) const;
size_type count(const key_type& k) const;
template<class K>
size_type count(const K& k) const;
bool contains(const key_type& k) const;
template<class K>
bool contains(const K& k) const;
pair<iterator, iterator> equal_range(const key_type& k);
pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
template<class K>
pair<iterator, iterator> equal_range(const K& k);
template<class K>
pair<const_iterator, const_iterator> equal_range(const K& k) const;
size_type bucket_count() const noexcept;
size_type max_bucket_count() const noexcept;
size_type bucket_size(size_type n) const;
size_type bucket(const key_type& k) const;
local_iterator begin(size_type n);
const_local_iterator begin(size_type n) const;
local_iterator end(size_type n);
const_local_iterator end(size_type n) const;
const_local_iterator cbegin(size_type n) const;
const_local_iterator cend(size_type n) const;
float load_factor() const noexcept;
float max_load_factor() const noexcept;
void max_load_factor(float z);
void rehash(size_type n);
void reserve(size_type n);};
template<class InputIterator, class Hash = hash<iter-value-type>, class Pred = equal_to<iter-value-type>, class Allocator = allocator<iter-value-type>> unordered_set(InputIterator, InputIterator, typename see below::size_type = see below, Hash = Hash(), Pred = Pred(), Allocator = Allocator()) -> unordered_set<iter-value-type, Hash, Pred, Allocator>;
template<class T, class Hash = hash, class Pred = equal_to, class Allocator = allocator> unordered_set(initializer_list, 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, hash<iter-value-type>, equal_to<iter-value-type>, Allocator>;
template<class InputIterator, class Hash, class Allocator> unordered_set(InputIterator, InputIterator, typename see below::size_type, Hash, Allocator) -> unordered_set<iter-value-type, Hash, equal_to<iter-value-type>, Allocator>;
template<class T, class Allocator> unordered_set(initializer_list, typename see below::size_type, Allocator) -> unordered_set<T, hash, equal_to, Allocator>;
template<class T, class Hash, class Allocator> unordered_set(initializer_list, typename see below::size_type, Hash, Allocator) -> unordered_set<T, Hash, equal_to, Allocator>;
template<class Key, class Hash, class Pred, class Alloc> void swap(unordered_set<Key, Hash, Pred, Alloc>& x, unordered_set<Key, Hash, Pred, Alloc>& y) noexcept(noexcept(x.swap(y))); }
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.
22.5.6.2 Constructors [unord.set.cnstr]
unordered_set() : unordered_set(size_type(see below)) { } explicit unordered_set(size_type n,const hasher& hf = hasher(),const key_equal& eql = key_equal(),const allocator_type& a = allocator_type());
Effects:Constructs an empty unordered_set using the specified hash function, key equality predicate, and allocator, and using at least n buckets.
For the default constructor, the number of buckets is implementation-defined.
max_load_factor() returns 1.0.
template<class InputIterator> 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()); 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());
Effects:Constructs an empty unordered_set using the specified hash function, key equality predicate, and allocator, and using at least n buckets.
If n is not provided, the number of buckets is implementation-defined.
Then inserts elements from the range [f, l)for the first form, or from the range[il.begin(), il.end()) for the second form.
max_load_factor() returns 1.0.
Complexity:Average case linear, worst case quadratic.
22.5.6.3 Erasure [unord.set.erasure]
template<class K, class H, class P, class A, class Predicate> typename unordered_set<K, H, P, A>::size_type erase_if(unordered_set<K, H, P, A>& c, Predicate pred);
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();
22.5.7 Class template unordered_multiset [unord.multiset]
22.5.7.1 Overview [unord.multiset.overview]
An unordered_multiset is an unordered associative container that supports equivalent keys (an instance of unordered_multiset may contain multiple copies of the same key value) and in which each element's key is the element itself.
The unordered_multiset class supports forward iterators.
An unordered_multiset meets all of the requirements of a container, of an unordered associative container, and of an allocator-aware container (Table 76).
It provides the operations described in the preceding requirements table for equivalent keys; that is, an unordered_multisetsupports the a_eq operations in that table, not the a_uniq operations.
For an unordered_multiset<Key> the key type and the value type are both Key.
The iterator and const_iterator types are both constant iterator types.
It is unspecified whether they are the same type.
Subclause [unord.multiset] only describes operations on unordered_multiset that are not described in one of the requirement tables, or for which there is additional semantic information.
namespace std { template<class Key, class Hash = hash, class Pred = equal_to, class Allocator = allocator> class unordered_multiset { public:
using 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;
using difference_type = implementation-defined;
using iterator = implementation-defined;
using const_iterator = implementation-defined;
using local_iterator = implementation-defined;
using const_local_iterator = implementation-defined;
using node_type = unspecified;
unordered_multiset();
explicit unordered_multiset(size_type n,
const hasher& hf = hasher(),
const key_equal& eql = key_equal(),
const allocator_type& a = allocator_type());
template<class InputIterator>
unordered_multiset(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());
unordered_multiset(const unordered_multiset&);
unordered_multiset(unordered_multiset&&);
explicit unordered_multiset(const Allocator&);
unordered_multiset(const unordered_multiset&, const Allocator&);
unordered_multiset(unordered_multiset&&, const Allocator&);
unordered_multiset(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());
unordered_multiset(size_type n, const allocator_type& a)
: unordered_multiset(n, hasher(), key_equal(), a) { }
unordered_multiset(size_type n, const hasher& hf, const allocator_type& a)
: unordered_multiset(n, hf, key_equal(), a) { }
template<class InputIterator>
unordered_multiset(InputIterator f, InputIterator l, size_type n, const allocator_type& a)
: unordered_multiset(f, l, n, hasher(), key_equal(), a) { }
template<class InputIterator>
unordered_multiset(InputIterator f, InputIterator l, size_type n, const hasher& hf,
const allocator_type& a)
: unordered_multiset(f, l, n, hf, key_equal(), a) { }
unordered_multiset(initializer_list<value_type> il, size_type n, const allocator_type& a)
: unordered_multiset(il, n, hasher(), key_equal(), a) { }
unordered_multiset(initializer_list<value_type> il, size_type n, const hasher& hf,
const allocator_type& a)
: unordered_multiset(il, n, hf, key_equal(), a) { }
~unordered_multiset();
unordered_multiset& operator=(const unordered_multiset&);
unordered_multiset& operator=(unordered_multiset&&)
noexcept(allocator_traits<Allocator>::is_always_equal::value &&
is_nothrow_move_assignable_v<Hash> &&
is_nothrow_move_assignable_v<Pred>);
unordered_multiset& operator=(initializer_list<value_type>);
allocator_type get_allocator() const noexcept;
iterator begin() noexcept;
const_iterator begin() const noexcept;
iterator end() noexcept;
const_iterator end() const noexcept;
const_iterator cbegin() const noexcept;
const_iterator cend() const noexcept;
[[nodiscard]] bool empty() const noexcept;
size_type size() const noexcept;
size_type max_size() const noexcept;
template<class... Args> iterator emplace(Args&&... args);
template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
iterator insert(const value_type& obj);
iterator insert(value_type&& obj);
iterator insert(const_iterator hint, const value_type& obj);
iterator insert(const_iterator hint, value_type&& obj);
template<class InputIterator> void insert(InputIterator first, InputIterator last);
void insert(initializer_list<value_type>);
node_type extract(const_iterator position);
node_type extract(const key_type& x);
iterator insert(node_type&& nh);
iterator insert(const_iterator hint, node_type&& nh);
iterator erase(iterator position);
iterator erase(const_iterator position);
size_type erase(const key_type& k);
iterator erase(const_iterator first, const_iterator last);
void swap(unordered_multiset&)
noexcept(allocator_traits<Allocator>::is_always_equal::value &&
is_nothrow_swappable_v<Hash> &&
is_nothrow_swappable_v<Pred>);
void clear() noexcept;
template<class H2, class P2>
void merge(unordered_multiset<Key, H2, P2, Allocator>& source);
template<class H2, class P2>
void merge(unordered_multiset<Key, H2, P2, Allocator>&& source);
template<class H2, class P2>
void merge(unordered_set<Key, H2, P2, Allocator>& source);
template<class H2, class P2>
void merge(unordered_set<Key, H2, P2, Allocator>&& source);
hasher hash_function() const;
key_equal key_eq() const;
iterator find(const key_type& k);
const_iterator find(const key_type& k) const;
template<class K>
iterator find(const K& k);
template<class K>
const_iterator find(const K& k) const;
size_type count(const key_type& k) const;
template<class K>
size_type count(const K& k) const;
bool contains(const key_type& k) const;
template<class K>
bool contains(const K& k) const;
pair<iterator, iterator> equal_range(const key_type& k);
pair<const_iterator, const_iterator> equal_range(const key_type& k) const;
template<class K>
pair<iterator, iterator> equal_range(const K& k);
template<class K>
pair<const_iterator, const_iterator> equal_range(const K& k) const;
size_type bucket_count() const noexcept;
size_type max_bucket_count() const noexcept;
size_type bucket_size(size_type n) const;
size_type bucket(const key_type& k) const;
local_iterator begin(size_type n);
const_local_iterator begin(size_type n) const;
local_iterator end(size_type n);
const_local_iterator end(size_type n) const;
const_local_iterator cbegin(size_type n) const;
const_local_iterator cend(size_type n) const;
float load_factor() const noexcept;
float max_load_factor() const noexcept;
void max_load_factor(float z);
void rehash(size_type n);
void reserve(size_type n);};
template<class InputIterator, class Hash = hash<iter-value-type>, class Pred = equal_to<iter-value-type>, class Allocator = allocator<iter-value-type>> unordered_multiset(InputIterator, InputIterator, see below::size_type = see below, Hash = Hash(), Pred = Pred(), Allocator = Allocator()) -> unordered_multiset<iter-value-type, Hash, Pred, Allocator>;
template<class T, class Hash = hash, class Pred = equal_to, class Allocator = allocator> unordered_multiset(initializer_list, typename see below::size_type = see below, Hash = Hash(), Pred = Pred(), Allocator = Allocator()) -> unordered_multiset<T, Hash, Pred, Allocator>;
template<class InputIterator, class Allocator> unordered_multiset(InputIterator, InputIterator, typename see below::size_type, Allocator) -> unordered_multiset<iter-value-type, hash<iter-value-type>, equal_to<iter-value-type>, Allocator>;
template<class InputIterator, class Hash, class Allocator> unordered_multiset(InputIterator, InputIterator, typename see below::size_type, Hash, Allocator) -> unordered_multiset<iter-value-type, Hash, equal_to<iter-value-type>, Allocator>;
template<class T, class Allocator> unordered_multiset(initializer_list, typename see below::size_type, Allocator) -> unordered_multiset<T, hash, equal_to, Allocator>;
template<class T, class Hash, class Allocator> unordered_multiset(initializer_list, typename see below::size_type, Hash, Allocator) -> unordered_multiset<T, Hash, equal_to, Allocator>;
template<class Key, class Hash, class Pred, class Alloc> void swap(unordered_multiset<Key, Hash, Pred, Alloc>& x, unordered_multiset<Key, Hash, Pred, Alloc>& y) noexcept(noexcept(x.swap(y))); }
A size_type parameter type in an unordered_multiset deduction guide refers to the size_type member type of the type deduced by the deduction guide.
22.5.7.2 Constructors [unord.multiset.cnstr]
unordered_multiset() : unordered_multiset(size_type(see below)) { } explicit unordered_multiset(size_type n,const hasher& hf = hasher(),const key_equal& eql = key_equal(),const allocator_type& a = allocator_type());
Effects:Constructs an empty unordered_multiset using the specified hash function, key equality predicate, and allocator, and using at least n buckets.
For the default constructor, the number of buckets is implementation-defined.
max_load_factor() returns 1.0.
template<class InputIterator> unordered_multiset(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()); unordered_multiset(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());
Effects:Constructs an empty unordered_multiset using the specified hash function, key equality predicate, and allocator, and using at least n buckets.
If n is not provided, the number of buckets is implementation-defined.
Then inserts elements from the range [f, l)for the first form, or from the range[il.begin(), il.end()) for the second form.
max_load_factor() returns 1.0.
Complexity:Average case linear, worst case quadratic.
22.5.7.3 Erasure [unord.multiset.erasure]
template<class K, class H, class P, class A, class Predicate> typename unordered_multiset<K, H, P, A>::size_type erase_if(unordered_multiset<K, H, P, A>& c, Predicate pred);
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();