is defined in the header file <unordered_set>
template<
class Key, > class unordered_multiset; |
(1) | (since C++ 11) |
namespace pmr {
template } |
(2) | (since C++ 17) |
unordered_multiset is an associative container containing a collection of objects of type Key that may not be unique. Search, insertion and removal have an average constant time complexity.
Elements are not sorted in any order internally, just organized into buckets. Which bucket an element is placed in depends entirely on the hash of its value. This allows for quick access to individual elements, since once the hash is computed, it refers to the exact bucket in which the element was placed.
The iteration order of this container is not required to be stable (so e.g. std::equal cannot be used to compare two std::unordered_multiset
), except for key comparisons equivalent (with key_eq( ) for the comparator compares equal) constitutes a contiguous subrange in iteration order, which can be accessed with equal_range().
Member function
Assign to container
std::unordered_multiset<Key,Hash,KeyEqual,Allocator>::operator=
unordered_multiset & amp; operator=( const unordered_multiset & amp; other ); |
(1) | (since C++ 11) |
unordered_multiset & amp; operator=( unordered_multiset & amp; & amp; other ); |
(2) | (since C++11) (until C++17) |
unordered_multiset & amp; operator=( unordered_multiset & amp; & amp; other ) noexcept(/* see below */); |
(since C++17) | |
unordered_multiset & operator=( std::initializer_list |
(3) | (since C++ 11) |
Replace container contents.
1) Copy assignment operator. Replace the content with a copy of other
. If std::allocator_traitsother
‘s allocator before copying the element. (since C++11).,
2) Move assignment operator. Replace the content with the content of other
using move semantics (i.e. move the data in other
from other
to this container). After other
is in a legal but unspecified state. If std::allocator_traits
3) Replace the contents with those identified by initializer_list ilist
.
parameter
other | – | Another container to use as a data source |
ilist | – | initializer_list used as data source |
Return value
*this
Complexity
1) Linear in size of *this
and other
.
2) Linear in the size of *this
, unless the allocator does not compare equal and does not propagate, in which case it is the same as that of *this
and other
The size is linear.
3) Linear in size of *this
and ilist
.
Exception 2) noexcept specifies: noexcept(std::allocator_traits & amp; & amp; std::is_nothrow_move_assignable & amp; & amp; std::is_nothrow_move_assignable |
Note
After container move assignment (overload(2)), references, pointers, and iterators (except tail iterators) to other
remain valid unless an incompatible allocator forces element-wise assignment, However the referred element is now in *this. The current standard guarantees this through blanket statements in §23.2.1[container.requirements.general]/12, while more direct guarantees are being considered under LWG 2321.
Returns the associated allocator
std::unordered_multiset<Key, Hash, KeyEqual, Allocator>::get_allocator
allocator_type get_allocator() const; |
(since C++11) |
Returns the allocator associated with the container.
parameter
(none)
Return value
The associated allocator.
Complexity
constant.
Call example
#include <iostream> #include <forward_list> #include <string> #include <iterator> #include <algorithm> #include <functional> #include <unordered_set> #include <time.h> using namespace std; struct Cell { int x; int y; Cell() = default; Cell(int a, int b): x(a), y(b) {} Cell & amp; operator + =(const Cell & amp; cell) { x + = cell.x; y + = cell.y; return *this; } Cell & amp; operator + (const Cell & amp; cell) { x + = cell.x; y + = cell.y; return *this; } Cell & amp; operator *(const Cell & amp; cell) { x *= cell.x; y *= cell.y; return *this; } Cell & operator + + () { x + = 1; y + = 1; return *this; } bool operator <(const Cell & cell) const { if (x == cell.x) { return y < cell.y; } else { return x < cell.x; } } bool operator >(const Cell & cell) const { if (x == cell.x) { return y > cell.y; } else { return x > cell.x; } } bool operator ==(const Cell & cell) const { return x == cell.x & amp; & amp; y == cell.y; } }; struct myCompare { bool operator()(const int & amp; a, const int & amp; b) { return a < b; } }; std::ostream & amp;operator<<(std::ostream & amp;os, const Cell & amp;cell) { os << "{" << cell.x << "," << cell.y << "}"; return os; } std::ostream & amp;operator<<(std::ostream & amp;os, const std::pair<const int, Cell> & amp;pCell) { os << pCell.first << "-" << pCell.second; return os; } struct CHash { size_t operator()(const Cell & cell) const { size_t thash = std::hash<int>()(cell.x) | std::hash<int>()(cell.y); // std::cout << "CHash: " <<thash << std::endl; return thash; } }; struct CEqual { bool operator()(const Cell & amp; a, const Cell & amp; b) const { return a.x == b.x & amp; & amp; a.y == b.y; } }; int main() { std::cout << std::boolalpha; std::mt19937 g{std::random_device{}()}; srand((unsigned)time(NULL)); auto generate = []() { int n = std::rand() % 10 + 110; Cell cell{n, n}; return cell; }; std::vector<Cell> vector1(6); std::generate(vector1. begin(), vector1. end(), generate); std::cout << "vector1: "; std::copy(vector1.begin(), vector1.end(), std::ostream_iterator<Cell>(std::cout, " ")); std::cout << std::endl; //2) Constructs a container with content in the range [first, last). // Set max_load_factor() to 1.0. If more than one element in the range has a key that compares equivalent, it is unspecified which element is inserted. std::unordered_multiset<Cell, CHash, CEqual> unordered_multiset1(vector1.begin(), vector1.end()); std::cout << "unordered_multiset1: "; std::copy(unordered_multiset1.begin(), unordered_multiset1.end(), std::ostream_iterator<Cell>(std::cout, " ")); std::cout << std::endl; std::cout << std::endl; //1) Copy assignment operator. Replace the content with a copy of other. std::unordered_multiset<Cell, CHash, CEqual> unordered_multiset2 = unordered_multiset1; std::cout << "unordered_multiset2: "; std::copy(unordered_multiset2.begin(), unordered_multiset2.end(), std::ostream_iterator<Cell>(std::cout, " ")); std::cout << std::endl; //2) Move assignment operator. Replaces the contents of other with the contents of other using move semantics (i.e. moves the data in other from other to this container). // After that other is in a legal but unspecified state. std::unordered_multiset<Cell, CHash, CEqual> unordered_multiset3 = std::move(unordered_multiset1); std::cout << "unordered_multiset3: "; std::copy(unordered_multiset3.begin(), unordered_multiset3.end(), std::ostream_iterator<Cell>(std::cout, " ")); std::cout << std::endl; //3) Replace the contents with those identified by the initializer_list ilist. std::unordered_multiset<Cell, CHash, CEqual> unordered_multiset4 = {generate(), generate(), generate(), generate(), generate(), generate()}; std::cout << "unordered_multiset4: "; std::copy(unordered_multiset4.begin(), unordered_multiset4.end(), std::ostream_iterator<Cell>(std::cout, " ")); std::cout << std::endl; return 0; }