[flat.multimap] # 23 Containers library [[containers]](./#containers) ## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.multimap) ### 23.6.9 Class template flat_multimap [flat.multimap] #### [23.6.9.1](#overview) Overview [[flat.multimap.overview]](flat.multimap.overview) [1](#overview-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18148) A flat_multimap 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 values of another type T based on the keys[.](#overview-1.sentence-1) flat_multimap supports iterators that meet the *Cpp17InputIterator* requirements and 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#L18161) A flat_multimap 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_multimap 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]](container.node "23.2.5 Node handles")), - [(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 map is linear, including the ones that take an insertion position iterator[.](#overview-2.sentence-2) [*Note [1](#overview-note-1)*: A flat_multimap does not meet the additional requirements of an allocator-aware container ([[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#L18183) A flat_multimap 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_multimap 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_multimap the key_type is Key and the value_type is pair[.](#overview-3.sentence-3) [4](#overview-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18193) Except as otherwise noted, operations on flat_multimap are equivalent to those of flat_map, except that flat_multimap operations do not remove or replace elements with equal keys[.](#overview-4.sentence-1) [*Example [1](#overview-example-1)*: flat_multimap constructors and emplace do not erase non-unique elements after sorting them[.](#overview-4.sentence-2) — *end example*] [5](#overview-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18203) A flat_multimap maintains the following invariants: - [(5.1)](#overview-5.1) it contains the same number of keys and values; - [(5.2)](#overview-5.2) the keys are sorted with respect to the comparison object; and - [(5.3)](#overview-5.3) the value at offset off within the value container is the value associated with the key at offset off within the key container[.](#overview-5.sentence-1) [6](#overview-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18215) If any member function in [[flat.multimap.defn]](#defn "23.6.9.2 Definition") exits via an exception, the invariants are restored[.](#overview-6.sentence-1) [*Note [2](#overview-note-2)*: This can result in the flat_multimap being emptied[.](#overview-6.sentence-2) — *end note*] [7](#overview-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18222) Any type C that meets the sequence container requirements ([[sequence.reqmts]](sequence.reqmts "23.2.4 Sequence containers")) can be used to instantiate flat_multimap, as long asC​::​iterator meets the *Cpp17RandomAccessIterator* requirements and invocations of member functions C​::​size and C​::​max_size do not exit via an exception[.](#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#L18236) The program is ill-formed ifKey is not the same type as KeyContainer​::​value_type orT is not the same type as MappedContainer​::​value_type[.](#overview-8.sentence-1) [9](#overview-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18241) The effect of calling a constructor that takes both key_container_type andmapped_container_type arguments with containers of different sizes is undefined[.](#overview-9.sentence-1) [10](#overview-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18247) The effect of calling a constructor or member function that takes a sorted_equivalent_t argument with a container, containers, or range that are not sorted with respect to key_comp() is undefined[.](#overview-10.sentence-1) [11](#overview-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18253) The types iterator and const_iterator meet the constexpr iterator requirements ([[iterator.requirements.general]](iterator.requirements.general "24.3.1 General"))[.](#overview-11.sentence-1) #### [23.6.9.2](#defn) Definition [[flat.multimap.defn]](flat.multimap.defn) namespace std {template, class KeyContainer = vector, class MappedContainer = vector>class flat_multimap {public:// typesusing key_type = Key; using mapped_type = T; using value_type = pair; using key_compare = Compare; using reference = pair; using const_reference = pair; using size_type = size_t; using difference_type = ptrdiff_t; 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 key_container_type = KeyContainer; using mapped_container_type = MappedContainer; class value_compare {private: key_compare *comp*; // *exposition only*constexpr value_compare(key_compare c) : *comp*(c) { } // *exposition only*public:constexpr bool operator()(const_reference x, const_reference y) const {return *comp*(x.first, y.first); }}; struct containers { key_container_type keys; mapped_container_type values; }; // [[flat.multimap.cons]](#cons "23.6.9.3 Constructors"), constructorsconstexpr flat_multimap() : flat_multimap(key_compare()) { }constexpr explicit flat_multimap(const key_compare& comp): *c*(), *compare*(comp) { }constexpr flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont, const key_compare& comp = key_compare()); constexpr flat_multimap(sorted_equivalent_t, key_container_type key_cont, mapped_container_type mapped_cont, const key_compare& comp = key_compare()); templateconstexpr flat_multimap(InputIterator first, InputIterator last, const key_compare& comp = key_compare()): *c*(), *compare*(comp){ insert(first, last); }templateconstexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, const key_compare& comp = key_compare()): *c*(), *compare*(comp) { insert(sorted_equivalent, first, last); }template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]") R>constexpr flat_multimap(from_range_t, R&& rg): flat_multimap(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_multimap(from_range_t, R&& rg, const key_compare& comp): flat_multimap(comp) { insert_range(std::forward(rg)); }constexpr flat_multimap(initializer_list il, const key_compare& comp = key_compare()): flat_multimap(il.begin(), il.end(), comp) { }constexpr flat_multimap(sorted_equivalent_t, initializer_list il, const key_compare& comp = key_compare()): flat_multimap(sorted_equivalent, il.begin(), il.end(), comp) { }// [[flat.multimap.cons.alloc]](#cons.alloc "23.6.9.4 Constructors with allocators"), constructors with allocatorstemplateconstexpr explicit flat_multimap(const Alloc& a); templateconstexpr flat_multimap(const key_compare& comp, const Alloc& a); templateconstexpr flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, const Alloc& a); templateconstexpr flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, const key_compare& comp, const Alloc& a); templateconstexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, const mapped_container_type& mapped_cont, const Alloc& a); templateconstexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, const mapped_container_type& mapped_cont, const key_compare& comp, const Alloc& a); templateconstexpr flat_multimap(const flat_multimap&, const Alloc& a); templateconstexpr flat_multimap(flat_multimap&&, const Alloc& a); templateconstexpr flat_multimap(InputIterator first, InputIterator last, const Alloc& a); templateconstexpr flat_multimap(InputIterator first, InputIterator last, const key_compare& comp, const Alloc& a); templateconstexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, const Alloc& a); templateconstexpr flat_multimap(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_multimap(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_multimap(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); templateconstexpr flat_multimap(initializer_list il, const Alloc& a); templateconstexpr flat_multimap(initializer_list il, const key_compare& comp, const Alloc& a); templateconstexpr flat_multimap(sorted_equivalent_t, initializer_list il, const Alloc& a); templateconstexpr flat_multimap(sorted_equivalent_t, initializer_list il, const key_compare& comp, const Alloc& a); flat_multimap& 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; // 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)); }template constexpr iterator insert(P&& x); templateconstexpr iterator insert(const_iterator position, P&&); 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 containers extract() &&; constexpr void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont); 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_multimap&) noexcept; constexpr void clear() noexcept; // observersconstexpr key_compare key_comp() const; constexpr value_compare value_comp() const; constexpr const key_container_type& keys() const noexcept { return *c*.keys; }constexpr const mapped_container_type& values() const noexcept { return *c*.values; }// map 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_multimap& x, const flat_multimap& y); friend constexpr *synth-three-way-result*operator<=>(const flat_multimap& x, const flat_multimap& y); friend constexpr void swap(flat_multimap& x, flat_multimap& y) noexcept{ x.swap(y); }private: containers *c*; // *exposition only* key_compare *compare*; // *exposition only*}; template> flat_multimap(KeyContainer, MappedContainer, Compare = Compare())-> flat_multimap; template flat_multimap(KeyContainer, MappedContainer, Allocator)-> flat_multimap, KeyContainer, MappedContainer>; template flat_multimap(KeyContainer, MappedContainer, Compare, Allocator)-> flat_multimap; template> flat_multimap(sorted_equivalent_t, KeyContainer, MappedContainer, Compare = Compare())-> flat_multimap; template flat_multimap(sorted_equivalent_t, KeyContainer, MappedContainer, Allocator)-> flat_multimap, KeyContainer, MappedContainer>; template flat_multimap(sorted_equivalent_t, KeyContainer, MappedContainer, Compare, Allocator)-> flat_multimap; template>> flat_multimap(InputIterator, InputIterator, Compare = Compare())-> flat_multimap<*iter-key-type*, *iter-mapped-type*, Compare>; template>> flat_multimap(sorted_equivalent_t, InputIterator, InputIterator, Compare = Compare())-> flat_multimap<*iter-key-type*, *iter-mapped-type*, Compare>; template>, class Allocator = allocator> flat_multimap(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())-> flat_multimap<*range-key-type*, *range-mapped-type*, Compare, vector<*range-key-type*, *alloc-rebind*>>, vector<*range-mapped-type*, *alloc-rebind*>>>; template flat_multimap(from_range_t, R&&, Allocator)-> flat_multimap<*range-key-type*, *range-mapped-type*, less<*range-key-type*>, vector<*range-key-type*, *alloc-rebind*>>, vector<*range-mapped-type*, *alloc-rebind*>>>; template> flat_multimap(initializer_list>, Compare = Compare())-> flat_multimap; template> flat_multimap(sorted_equivalent_t, initializer_list>, Compare = Compare())-> flat_multimap; templatestruct uses_allocator, Allocator>: bool_constant && uses_allocator_v> { };} [1](#defn-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18572) The member type containers has the data members and special members specified above[.](#defn-1.sentence-1) It has no base classes or members other than those specified[.](#defn-1.sentence-2) #### [23.6.9.3](#cons) Constructors [[flat.multimap.cons]](flat.multimap.cons) [🔗](#lib:flat_multimap,constructor) `constexpr flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont, const key_compare& comp = key_compare()); ` [1](#cons-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18586) *Effects*: Initializes*c*.keys with std​::​move(key_cont),*c*.values with std​::​move(mapped_cont), and*compare* with comp; sorts the range [begin(), end()) with respect to value_comp()[.](#cons-1.sentence-1) [2](#cons-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18594) *Complexity*: Linear in N if the container arguments are already sorted with respect to value_comp() and otherwise NlogN, where N is the value of key_cont.size() before this call[.](#cons-2.sentence-1) [🔗](#lib:flat_multimap,constructor_) `constexpr flat_multimap(sorted_equivalent_t, key_container_type key_cont, mapped_container_type mapped_cont, const key_compare& comp = key_compare()); ` [3](#cons-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18609) *Effects*: Initializes*c*.keys with std​::​move(key_cont),*c*.values with std​::​move(mapped_cont), and*compare* with comp[.](#cons-3.sentence-1) [4](#cons-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18616) *Complexity*: Constant[.](#cons-4.sentence-1) #### [23.6.9.4](#cons.alloc) Constructors with allocators [[flat.multimap.cons.alloc]](flat.multimap.cons.alloc) [1](#cons.alloc-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18623) The constructors in this subclause shall not participate in overload resolution unless uses_allocator_v is true and uses_allocator_v is true[.](#cons.alloc-1.sentence-1) [🔗](#lib:flat_multimap,constructor__) `template constexpr flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, const Alloc& a); template constexpr flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, const key_compare& comp, const Alloc& a); ` [2](#cons.alloc-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18640) *Effects*: Equivalent to flat_multimap(key_cont, mapped_cont) andflat_multimap(key_cont, mapped_cont, comp), respectively, except that *c*.keys and *c*.values are 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#L18647) *Complexity*: Same as flat_multimap(key_cont, mapped_cont) andflat_multimap(key_cont, mapped_cont, comp), respectively[.](#cons.alloc-3.sentence-1) [🔗](#lib:flat_multimap,constructor___) `template constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, const mapped_container_type& mapped_cont, const Alloc& a); template constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, const mapped_container_type& mapped_cont, const key_compare& comp, const Alloc& a); ` [4](#cons.alloc-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18665) *Effects*: Equivalent to flat_multimap(sorted_equivalent, key_cont, mapped_cont) andflat_multimap(sorted_equivalent, key_cont, mapped_cont, comp), respectively, except that *c*.keys and *c*.values are 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#L18672) *Complexity*: Linear[.](#cons.alloc-5.sentence-1) [🔗](#lib:flat_multimap,constructor____) `template constexpr explicit flat_multimap(const Alloc& a); template constexpr flat_multimap(const key_compare& comp, const Alloc& a); template constexpr flat_multimap(const flat_multimap&, const Alloc& a); template constexpr flat_multimap(flat_multimap&&, const Alloc& a); template constexpr flat_multimap(InputIterator first, InputIterator last, const Alloc& a); template constexpr flat_multimap(InputIterator first, InputIterator last, const key_compare& comp, const Alloc& a); template constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, const Alloc& a); template constexpr flat_multimap(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_multimap(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_multimap(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); template constexpr flat_multimap(initializer_list il, const Alloc& a); template constexpr flat_multimap(initializer_list il, const key_compare& comp, const Alloc& a); template constexpr flat_multimap(sorted_equivalent_t, initializer_list il, const Alloc& a); template constexpr flat_multimap(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#L18715) *Effects*: Equivalent to the corresponding non-allocator constructors except that *c*.keys and *c*.values are 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.9.5](#erasure) Erasure [[flat.multimap.erasure]](flat.multimap.erasure) [🔗](#lib:erase_if,flat_multimap) `template constexpr typename flat_multimap::size_type erase_if(flat_multimap& c, Predicate pred); ` [1](#erasure-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18733) *Preconditions*: Key and T meet the *Cpp17MoveAssignable* requirements[.](#erasure-1.sentence-1) [2](#erasure-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18737) *Effects*: Let E be bool(pred(pair(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#L18742) *Returns*: The number of elements erased[.](#erasure-3.sentence-1) [4](#erasure-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18746) *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#L18750) *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*]