[flat.multiset] # 23 Containers library [[containers]](./#containers) ## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.multiset) ### 23.6.12 Class template flat_multiset [flat.multiset] #### [23.6.12.1](#overview) Overview [[flat.multiset.overview]](flat.multiset.overview) [1](#overview-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19475) A flat_multiset is a container adaptor that provides an associative container interface that supports equivalent keys (i.e., possibly containing multiple copies of the same key value) and provides for fast retrieval of the keys themselves[.](#overview-1.sentence-1) flat_multiset supports iterators that model the[random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_­access_­iterator [iterator.concept.random.access]") concept ([[iterator.concept.random.access]](iterator.concept.random.access "24.3.4.13 Concept random_­access_­iterator"))[.](#overview-1.sentence-2) [2](#overview-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19485) A flat_multiset meets all of the requirements for a container ([[container.reqmts]](container.reqmts "23.2.2.2 Container requirements")) and for a reversible container ([[container.rev.reqmts]](container.rev.reqmts "23.2.2.3 Reversible container requirements")), plus the optional container requirements ([[container.opt.reqmts]](container.opt.reqmts "23.2.2.4 Optional container requirements"))[.](#overview-2.sentence-1) flat_multiset meets the requirements of an associative container ([[associative.reqmts]](associative.reqmts "23.2.7 Associative containers")), except that: - [(2.1)](#overview-2.1) it does not meet the requirements related to node handles ([[container.node.overview]](container.node.overview "23.2.5.1 Overview")), - [(2.2)](#overview-2.2) it does not meet the requirements related to iterator invalidation, and - [(2.3)](#overview-2.3) the time complexity of the operations that insert or erase a single element from the set is linear, including the ones that take an insertion position iterator[.](#overview-2.sentence-2) [*Note [1](#overview-note-1)*: A flat_multiset does not meet the additional requirements of an allocator-aware container, as described in [[container.alloc.reqmts]](container.alloc.reqmts "23.2.2.5 Allocator-aware containers")[.](#overview-2.sentence-3) — *end note*] [3](#overview-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19510) A flat_multiset also provides most operations described in [[associative.reqmts]](associative.reqmts "23.2.7 Associative containers") for equal keys[.](#overview-3.sentence-1) This means that a flat_multiset supports the a_eq operations in [[associative.reqmts]](associative.reqmts "23.2.7 Associative containers") but not the a_uniq operations[.](#overview-3.sentence-2) For a flat_multiset, both the key_type and value_type are Key[.](#overview-3.sentence-3) [4](#overview-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19519) Descriptions are provided here only for operations on flat_multiset that are not described in one of the general sections or for operations where there is additional semantic information[.](#overview-4.sentence-1) [5](#overview-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19524) A flat_multiset maintains the invariant that the keys are sorted with respect to the comparison object[.](#overview-5.sentence-1) [6](#overview-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19528) If any member function in [[flat.multiset.defn]](#defn "23.6.12.2 Definition") exits via an exception, the invariant is restored[.](#overview-6.sentence-1) [*Note [2](#overview-note-2)*: This can result in the flat_multiset's being emptied[.](#overview-6.sentence-2) — *end note*] [7](#overview-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19535) Any sequence container ([[sequence.reqmts]](sequence.reqmts "23.2.4 Sequence containers")) supporting *Cpp17RandomAccessIterator* can be used to instantiate flat_multiset[.](#overview-7.sentence-1) In particular,vector ([[vector]](vector "23.3.13 Class template vector")) and deque ([[deque]](deque "23.3.5 Class template deque")) can be used[.](#overview-7.sentence-2) [*Note [3](#overview-note-3)*: vector is not a sequence container[.](#overview-7.sentence-3) — *end note*] [8](#overview-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19545) The program is ill-formed if Key is not the same type as KeyContainer​::​value_type[.](#overview-8.sentence-1) [9](#overview-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19549) The effect of calling a constructor or member function that takes a sorted_equivalent_t argument with a range that is not sorted with respect to key_comp() is undefined[.](#overview-9.sentence-1) [10](#overview-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19554) The types iterator and const_iterator meet the constexpr iterator requirements ([[iterator.requirements.general]](iterator.requirements.general "24.3.1 General"))[.](#overview-10.sentence-1) #### [23.6.12.2](#defn) Definition [[flat.multiset.defn]](flat.multiset.defn) namespace std {template, class KeyContainer = vector>class flat_multiset {public:// typesusing key_type = Key; using value_type = Key; using key_compare = Compare; using value_compare = Compare; using reference = value_type&; using const_reference = const value_type&; using size_type = typename KeyContainer::size_type; using difference_type = typename KeyContainer::difference_type; using iterator = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2 Requirements")using const_iterator = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2 Requirements")using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; using container_type = KeyContainer; // [[flat.multiset.cons]](#cons "23.6.12.3 Constructors"), constructorsconstexpr flat_multiset() : flat_multiset(key_compare()) { }constexpr explicit flat_multiset(const key_compare& comp): *c*(), *compare*(comp) { }constexpr explicit flat_multiset(container_type cont, const key_compare& comp = key_compare()); constexpr flat_multiset(sorted_equivalent_t, container_type cont, const key_compare& comp = key_compare()): *c*(std::move(cont)), *compare*(comp) { }templateconstexpr flat_multiset(InputIterator first, InputIterator last, const key_compare& comp = key_compare()): *c*(), *compare*(comp){ insert(first, last); }templateconstexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, const key_compare& comp = key_compare()): *c*(first, last), *compare*(comp) { }template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]") R>constexpr flat_multiset(from_range_t, R&& rg): flat_multiset(from_range, std::forward(rg), key_compare()) { }template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]") R>constexpr flat_multiset(from_range_t, R&& rg, const key_compare& comp): flat_multiset(comp){ insert_range(std::forward(rg)); }constexpr flat_multiset(initializer_list il, const key_compare& comp = key_compare()): flat_multiset(il.begin(), il.end(), comp) { }constexpr flat_multiset(sorted_equivalent_t, initializer_list il, const key_compare& comp = key_compare()): flat_multiset(sorted_equivalent, il.begin(), il.end(), comp) { }// [[flat.multiset.cons.alloc]](#cons.alloc "23.6.12.4 Constructors with allocators"), constructors with allocatorstemplateconstexpr explicit flat_multiset(const Alloc& a); templateconstexpr flat_multiset(const key_compare& comp, const Alloc& a); templateconstexpr flat_multiset(const container_type& cont, const Alloc& a); templateconstexpr flat_multiset(const container_type& cont, const key_compare& comp, const Alloc& a); templateconstexpr flat_multiset(sorted_equivalent_t, const container_type& cont, const Alloc& a); templateconstexpr flat_multiset(sorted_equivalent_t, const container_type& cont, const key_compare& comp, const Alloc& a); templateconstexpr flat_multiset(const flat_multiset&, const Alloc& a); templateconstexpr flat_multiset(flat_multiset&&, const Alloc& a); templateconstexpr flat_multiset(InputIterator first, InputIterator last, const Alloc& a); templateconstexpr flat_multiset(InputIterator first, InputIterator last, const key_compare& comp, const Alloc& a); templateconstexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, const Alloc& a); templateconstexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, const key_compare& comp, const Alloc& a); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]") R, class Alloc>constexpr flat_multiset(from_range_t, R&& rg, const Alloc& a); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]") R, class Alloc>constexpr flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); templateconstexpr flat_multiset(initializer_list il, const Alloc& a); templateconstexpr flat_multiset(initializer_list il, const key_compare& comp, const Alloc& a); templateconstexpr flat_multiset(sorted_equivalent_t, initializer_list il, const Alloc& a); templateconstexpr flat_multiset(sorted_equivalent_t, initializer_list il, const key_compare& comp, const Alloc& a); constexpr flat_multiset& operator=(initializer_list); // iteratorsconstexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept; constexpr iterator end() noexcept; constexpr const_iterator end() const noexcept; constexpr reverse_iterator rbegin() noexcept; constexpr const_reverse_iterator rbegin() const noexcept; constexpr reverse_iterator rend() noexcept; constexpr const_reverse_iterator rend() const noexcept; constexpr const_iterator cbegin() const noexcept; constexpr const_iterator cend() const noexcept; constexpr const_reverse_iterator crbegin() const noexcept; constexpr const_reverse_iterator crend() const noexcept; // capacityconstexpr bool empty() const noexcept; constexpr size_type size() const noexcept; constexpr size_type max_size() const noexcept; // [[flat.multiset.modifiers]](#modifiers "23.6.12.5 Modifiers"), modifierstemplate constexpr iterator emplace(Args&&... args); templateconstexpr iterator emplace_hint(const_iterator position, Args&&... args); constexpr iterator insert(const value_type& x){ return emplace(x); }constexpr iterator insert(value_type&& x){ return emplace(std::move(x)); }constexpr iterator insert(const_iterator position, const value_type& x){ return emplace_hint(position, x); }constexpr iterator insert(const_iterator position, value_type&& x){ return emplace_hint(position, std::move(x)); }templateconstexpr void insert(InputIterator first, InputIterator last); templateconstexpr void insert(sorted_equivalent_t, InputIterator first, InputIterator last); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]") R>constexpr void insert_range(R&& rg); constexpr void insert(initializer_list il){ insert(il.begin(), il.end()); }constexpr void insert(sorted_equivalent_t, initializer_list il){ insert(sorted_equivalent, il.begin(), il.end()); }constexpr container_type extract() &&; constexpr void replace(container_type&&); constexpr iterator erase(iterator position); constexpr iterator erase(const_iterator position); constexpr size_type erase(const key_type& x); template constexpr size_type erase(K&& x); constexpr iterator erase(const_iterator first, const_iterator last); constexpr void swap(flat_multiset& y) noexcept; constexpr void clear() noexcept; // observersconstexpr key_compare key_comp() const; constexpr value_compare value_comp() const; // set operationsconstexpr iterator find(const key_type& x); constexpr const_iterator find(const key_type& x) const; template constexpr iterator find(const K& x); template constexpr const_iterator find(const K& x) const; constexpr size_type count(const key_type& x) const; template constexpr size_type count(const K& x) const; constexpr bool contains(const key_type& x) const; template constexpr bool contains(const K& x) const; constexpr iterator lower_bound(const key_type& x); constexpr const_iterator lower_bound(const key_type& x) const; template constexpr iterator lower_bound(const K& x); template constexpr const_iterator lower_bound(const K& x) const; constexpr iterator upper_bound(const key_type& x); constexpr const_iterator upper_bound(const key_type& x) const; template constexpr iterator upper_bound(const K& x); template constexpr const_iterator upper_bound(const K& x) const; constexpr pair equal_range(const key_type& x); constexpr pair equal_range(const key_type& x) const; templateconstexpr pair equal_range(const K& x); templateconstexpr pair equal_range(const K& x) const; friend constexpr bool operator==(const flat_multiset& x, const flat_multiset& y); friend constexpr *synth-three-way-result*operator<=>(const flat_multiset& x, const flat_multiset& y); friend constexpr void swap(flat_multiset& x, flat_multiset& y) noexcept{ x.swap(y); }private: container_type *c*; // *exposition only* key_compare *compare*; // *exposition only*}; template> flat_multiset(KeyContainer, Compare = Compare())-> flat_multiset; template flat_multiset(KeyContainer, Allocator)-> flat_multiset, KeyContainer>; template flat_multiset(KeyContainer, Compare, Allocator)-> flat_multiset; template> flat_multiset(sorted_equivalent_t, KeyContainer, Compare = Compare())-> flat_multiset; template flat_multiset(sorted_equivalent_t, KeyContainer, Allocator)-> flat_multiset, KeyContainer>; template flat_multiset(sorted_equivalent_t, KeyContainer, Compare, Allocator)-> flat_multiset; template>> flat_multiset(InputIterator, InputIterator, Compare = Compare())-> flat_multiset<*iter-value-type*, Compare>; template>> flat_multiset(sorted_equivalent_t, InputIterator, InputIterator, Compare = Compare())-> flat_multiset<*iter-value-type*, Compare>; template>, class Allocator = allocator>> flat_multiset(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())-> flat_multiset, Compare, vector, *alloc-rebind*>>>; template flat_multiset(from_range_t, R&&, Allocator)-> flat_multiset, less>, vector, *alloc-rebind*>>>; template> flat_multiset(initializer_list, Compare = Compare())-> flat_multiset; template> flat_multiset(sorted_equivalent_t, initializer_list, Compare = Compare())-> flat_multiset; templatestruct uses_allocator, Allocator>: bool_constant> { };} #### [23.6.12.3](#cons) Constructors [[flat.multiset.cons]](flat.multiset.cons) [🔗](#lib:flat_multiset,constructor) `constexpr explicit flat_multiset(container_type cont, const key_compare& comp = key_compare()); ` [1](#cons-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19839) *Effects*: Initializes *c* with std​::​move(cont) and*compare* with comp, and sorts the range [begin(), end()) with respect to *compare*[.](#cons-1.sentence-1) [2](#cons-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19845) *Complexity*: Linear in N if cont is already sorted with respect to *compare* and otherwise NlogN, where N is the value of cont.size() before this call[.](#cons-2.sentence-1) #### [23.6.12.4](#cons.alloc) Constructors with allocators [[flat.multiset.cons.alloc]](flat.multiset.cons.alloc) [1](#cons.alloc-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19853) The constructors in this subclause shall not participate in overload resolution unless uses_allocator_v is true[.](#cons.alloc-1.sentence-1) [🔗](#lib:flat_multiset,constructor_) `template constexpr flat_multiset(const container_type& cont, const Alloc& a); template constexpr flat_multiset(const container_type& cont, const key_compare& comp, const Alloc& a); ` [2](#cons.alloc-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19866) *Effects*: Equivalent to flat_multiset(cont) andflat_multiset(cont, comp), respectively, except that *c* is constructed with uses-allocator construction ([[allocator.uses.construction]](allocator.uses.construction "20.2.8.2 Uses-allocator construction"))[.](#cons.alloc-2.sentence-1) [3](#cons.alloc-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19873) *Complexity*: Same as flat_multiset(cont) andflat_multiset(cont, comp), respectively[.](#cons.alloc-3.sentence-1) [🔗](#lib:flat_multiset,constructor__) `template constexpr flat_multiset(sorted_equivalent_t, const container_type& cont, const Alloc& a); template constexpr flat_multiset(sorted_equivalent_t, const container_type& cont, const key_compare& comp, const Alloc& a); ` [4](#cons.alloc-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19889) *Effects*: Equivalent to flat_multiset(sorted_equivalent, cont) andflat_multiset(sorted_equivalent, cont, comp), respectively, except that *c* is constructed with uses-allocator construction ([[allocator.uses.construction]](allocator.uses.construction "20.2.8.2 Uses-allocator construction"))[.](#cons.alloc-4.sentence-1) [5](#cons.alloc-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19896) *Complexity*: Linear[.](#cons.alloc-5.sentence-1) [🔗](#lib:flat_multiset,constructor___) `template constexpr explicit flat_multiset(const Alloc& a); template constexpr flat_multiset(const key_compare& comp, const Alloc& a); template constexpr flat_multiset(const flat_multiset&, const Alloc& a); template constexpr flat_multiset(flat_multiset&&, const Alloc& a); template constexpr flat_multiset(InputIterator first, InputIterator last, const Alloc& a); template constexpr flat_multiset(InputIterator first, InputIterator last, const key_compare& comp, const Alloc& a); template constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, const Alloc& a); template constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, const key_compare& comp, const Alloc& a); template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]") R, class Alloc> constexpr flat_multiset(from_range_t, R&& rg, const Alloc& a); template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]") R, class Alloc> constexpr flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); template constexpr flat_multiset(initializer_list il, const Alloc& a); template constexpr flat_multiset(initializer_list il, const key_compare& comp, const Alloc& a); template constexpr flat_multiset(sorted_equivalent_t, initializer_list il, const Alloc& a); template constexpr flat_multiset(sorted_equivalent_t, initializer_list il, const key_compare& comp, const Alloc& a); ` [6](#cons.alloc-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19939) *Effects*: Equivalent to the corresponding non-allocator constructors except that *c* is constructed with uses-allocator construction ([[allocator.uses.construction]](allocator.uses.construction "20.2.8.2 Uses-allocator construction"))[.](#cons.alloc-6.sentence-1) #### [23.6.12.5](#modifiers) Modifiers [[flat.multiset.modifiers]](flat.multiset.modifiers) [🔗](#lib:emplace,flat_multiset) `template constexpr iterator emplace(Args&&... args); ` [1](#modifiers-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19954) *Constraints*: is_constructible_v is true[.](#modifiers-1.sentence-1) [2](#modifiers-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19958) *Effects*: First, initializes an object t of type value_type with std​::​forward(args)..., then inserts t as if by:auto it = ranges::upper_bound(*c*, t, *compare*);*c*.insert(it, std::move(t)); [3](#modifiers-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19968) *Returns*: An iterator that points to the inserted element[.](#modifiers-3.sentence-1) [🔗](#lib:insert,flat_multiset) `template constexpr void insert(InputIterator first, InputIterator last); ` [4](#modifiers-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19980) *Effects*: Adds elements to *c* as if by:*c*.insert(*c*.end(), first, last); Then, sorts the range of newly inserted elements with respect to *compare*, and merges the resulting sorted range and the sorted range of pre-existing elements into a single sorted range[.](#modifiers-4.sentence-2) [5](#modifiers-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19990) *Complexity*: N + MlogM, where N is size() before the operation and M is distance(first, last)[.](#modifiers-5.sentence-1) [6](#modifiers-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19995) *Remarks*: Since this operation performs an in-place merge, it may allocate memory[.](#modifiers-6.sentence-1) [🔗](#lib:insert,flat_multiset_) `template constexpr void insert(sorted_equivalent_t, InputIterator first, InputIterator last); ` [7](#modifiers-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20007) *Effects*: Equivalent to insert(first, last)[.](#modifiers-7.sentence-1) [8](#modifiers-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20011) *Complexity*: Linear[.](#modifiers-8.sentence-1) [🔗](#lib:swap,flat_multiset) `constexpr void swap(flat_multiset& y) noexcept; ` [9](#modifiers-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20022) *Effects*: Equivalent to:ranges::swap(*compare*, y.*compare*); ranges::swap(*c*, y.*c*); [🔗](#lib:extract,flat_multiset) `constexpr container_type extract() &&; ` [10](#modifiers-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20037) *Postconditions*: *this is emptied, even if the function exits via an exception[.](#modifiers-10.sentence-1) [11](#modifiers-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20041) *Returns*: std​::​move(*c*)[.](#modifiers-11.sentence-1) [🔗](#lib:replace,flat_multiset) `constexpr void replace(container_type&& cont); ` [12](#modifiers-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20052) *Preconditions*: The elements of cont are sorted with respect to *compare*[.](#modifiers-12.sentence-1) [13](#modifiers-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20056) *Effects*: Equivalent to: *c* = std​::​move(cont); #### [23.6.12.6](#erasure) Erasure [[flat.multiset.erasure]](flat.multiset.erasure) [🔗](#lib:erase_if,flat_multiset) `template constexpr typename flat_multiset::size_type erase_if(flat_multiset& c, Predicate pred); ` [1](#erasure-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20071) *Preconditions*: Key meets the *Cpp17MoveAssignable* requirements[.](#erasure-1.sentence-1) [2](#erasure-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20075) *Effects*: Let E be bool(pred(as_const(e)))[.](#erasure-2.sentence-1) Erases all elements e in c for which E holds[.](#erasure-2.sentence-2) [3](#erasure-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20080) *Returns*: The number of elements erased[.](#erasure-3.sentence-1) [4](#erasure-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20084) *Complexity*: Exactly c.size() applications of the predicate[.](#erasure-4.sentence-1) [5](#erasure-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20088) *Remarks*: Stable ([[algorithm.stable]](algorithm.stable "16.4.6.8 Requirements for stable algorithms"))[.](#erasure-5.sentence-1) If an invocation of erase_if exits via an exception,c is in a valid but unspecified state ([[defns.valid]](defns.valid "3.67 valid but unspecified state"))[.](#erasure-5.sentence-2) [*Note [1](#erasure-note-1)*: c still meets its invariants, but can be empty[.](#erasure-5.sentence-3) — *end note*]