[map] # 23 Containers library [[containers]](./#containers) ## 23.4 Associative containers [[associative]](associative#map) ### 23.4.3 Class template map [map] #### [23.4.3.1](#overview) Overview [[map.overview]](map.overview) [1](#overview-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11467) A map is an associative container that supports unique keys (i.e., contains at most one of each key value) and provides for fast retrieval of values of another type T based on the keys[.](#overview-1.sentence-1) The map class supports bidirectional iterators[.](#overview-1.sentence-2) [2](#overview-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11473) A map meets all of the requirements of a container ([[container.reqmts]](container.reqmts "23.2.2.2 Container requirements")), of a reversible container ([[container.rev.reqmts]](container.rev.reqmts "23.2.2.3 Reversible container requirements")), of an allocator-aware container ([[container.alloc.reqmts]](container.alloc.reqmts "23.2.2.5 Allocator-aware containers")), and of an associative container ([[associative.reqmts]](associative.reqmts "23.2.7 Associative containers"))[.](#overview-2.sentence-1) Amap also provides most operations described in [[associative.reqmts]](associative.reqmts "23.2.7 Associative containers") for unique keys[.](#overview-2.sentence-2) This means that amap supports thea_uniq operations in [[associative.reqmts]](associative.reqmts "23.2.7 Associative containers") but not thea_eq operations[.](#overview-2.sentence-3) For amap thekey_type isKey and thevalue_type ispair[.](#overview-2.sentence-4) Descriptions are provided here only for operations onmap that are not described in one of those tables or for operations where there is additional semantic information[.](#overview-2.sentence-5) [3](#overview-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11506) The types iterator and const_iterator meet the constexpr iterator requirements ([[iterator.requirements.general]](iterator.requirements.general "24.3.1 General"))[.](#overview-3.sentence-1) [🔗](#lib:comp,map::value_compare) namespace std {template, class Allocator = allocator>>class map {public:// typesusing key_type = Key; using mapped_type = T; using value_type = pair; using key_compare = Compare; using allocator_type = Allocator; using pointer = typename allocator_traits::pointer; using const_pointer = typename allocator_traits::const_pointer; using reference = value_type&; using const_reference = const value_type&; using size_type = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2 Requirements")using difference_type = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2 Requirements")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 node_type = *unspecified*; using insert_return_type = *insert-return-type*; class value_compare {protected: Compare comp; constexpr value_compare(Compare c) : comp(c) {}public:constexpr bool operator()(const value_type& x, const value_type& y) const {return comp(x.first, y.first); }}; // [[map.cons]](#cons "23.4.3.2 Constructors, copy, and assignment"), construct/copy/destroyconstexpr map() : map(Compare()) { }constexpr explicit map(const Compare& comp, const Allocator& = Allocator()); templateconstexpr map(InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator()); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]") R>constexpr map(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); constexpr map(const map& x); constexpr map(map&& x); explicit map(const Allocator&); constexpr map(const map&, const type_identity_t&); constexpr map(map&&, const type_identity_t&); constexpr map(initializer_list, const Compare& = Compare(), const Allocator& = Allocator()); templateconstexpr map(InputIterator first, InputIterator last, const Allocator& a): map(first, last, Compare(), a) { }template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]") R>constexpr map(from_range_t, R&& rg, const Allocator& a): map(from_range, std::forward(rg), Compare(), a) { }constexpr map(initializer_list il, const Allocator& a): map(il, Compare(), a) { }constexpr ~map(); constexpr map& operator=(const map& x); constexpr map& operator=(map&& x)noexcept(allocator_traits::is_always_equal::value && is_nothrow_move_assignable_v); constexpr map& operator=(initializer_list); constexpr allocator_type get_allocator() const noexcept; // iteratorsconstexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept; constexpr iterator end() noexcept; constexpr const_iterator end() const noexcept; constexpr 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; // [[map.access]](#access "23.4.3.3 Element access"), element accessconstexpr mapped_type& operator[](const key_type& x); constexpr mapped_type& operator[](key_type&& x); template constexpr mapped_type& operator[](K&& x); constexpr mapped_type& at(const key_type& x); constexpr const mapped_type& at(const key_type& x) const; template constexpr mapped_type& at(const K& x); template constexpr const mapped_type& at(const K& x) const; // [[map.modifiers]](#modifiers "23.4.3.4 Modifiers"), modifierstemplate constexpr pair emplace(Args&&... args); templateconstexpr iterator emplace_hint(const_iterator position, Args&&... args); constexpr pair insert(const value_type& x); constexpr pair insert(value_type&& x); template constexpr pair insert(P&& x); constexpr iterator insert(const_iterator position, const value_type& x); constexpr iterator insert(const_iterator position, value_type&& x); templateconstexpr iterator insert(const_iterator position, P&&); templateconstexpr void insert(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); constexpr node_type extract(const_iterator position); constexpr node_type extract(const key_type& x); template constexpr node_type extract(K&& x); constexpr insert_return_type insert(node_type&& nh); constexpr iterator insert(const_iterator hint, node_type&& nh); templateconstexpr pair try_emplace(const key_type& k, Args&&... args); templateconstexpr pair try_emplace(key_type&& k, Args&&... args); templateconstexpr pair try_emplace(K&& k, Args&&... args); templateconstexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); templateconstexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); templateconstexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args); templateconstexpr pair insert_or_assign(const key_type& k, M&& obj); templateconstexpr pair insert_or_assign(key_type&& k, M&& obj); templateconstexpr pair insert_or_assign(K&& k, M&& obj); templateconstexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); templateconstexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); templateconstexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); 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(map&)noexcept(allocator_traits::is_always_equal::value && is_nothrow_swappable_v); constexpr void clear() noexcept; templateconstexpr void merge(map& source); templateconstexpr void merge(map&& source); templateconstexpr void merge(multimap& source); templateconstexpr void merge(multimap&& source); // observersconstexpr key_compare key_comp() const; constexpr value_compare value_comp() const; // 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; }; template>, class Allocator = allocator<*iter-to-alloc-type*>> map(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())-> map<*iter-key-type*, *iter-mapped-type*, Compare, Allocator>; template, class Allocator = allocator<*range-to-alloc-type*>> map(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())-> map<*range-key-type*, *range-mapped-type*, Compare, Allocator>; template, class Allocator = allocator>> map(initializer_list>, Compare = Compare(), Allocator = Allocator())-> map; template map(InputIterator, InputIterator, Allocator)-> map<*iter-key-type*, *iter-mapped-type*, less<*iter-key-type*>, Allocator>; template map(from_range_t, R&&, Allocator)-> map<*range-key-type*, *range-mapped-type*, less<*range-key-type*>, Allocator>; template map(initializer_list>, Allocator) -> map, Allocator>;} #### [23.4.3.2](#cons) Constructors, copy, and assignment [[map.cons]](map.cons) [🔗](#lib:map,constructor) `constexpr explicit map(const Compare& comp, const Allocator& = Allocator()); ` [1](#cons-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11751) *Effects*: Constructs an emptymap using the specified comparison object and allocator[.](#cons-1.sentence-1) [2](#cons-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11757) *Complexity*: Constant[.](#cons-2.sentence-1) [🔗](#lib:map,constructor_) `template constexpr map(InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator()); ` [3](#cons-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11770) *Effects*: Constructs an emptymap using the specified comparison object and allocator, and inserts elements from the range [first, last)[.](#cons-3.sentence-1) [4](#cons-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11778) *Complexity*: Linear in N if the range [first, last) is already sorted with respect to comp and otherwise NlogN, where N is last - first[.](#cons-4.sentence-1) [🔗](#lib:map,constructor__) `template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]") R> constexpr map(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); ` [5](#cons-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11795) *Effects*: Constructs an empty map using the specified comparison object and allocator, and inserts elements from the range rg[.](#cons-5.sentence-1) [6](#cons-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11801) *Complexity*: Linear in N if rg is already sorted with respect to comp and otherwise NlogN, where N is ranges​::​distance(rg)[.](#cons-6.sentence-1) #### [23.4.3.3](#access) Element access [[map.access]](map.access) [🔗](#lib:operator%5b%5d,map) `constexpr mapped_type& operator[](const key_type& x); ` [1](#access-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11815) *Effects*: Equivalent to: return try_emplace(x).first->second; [🔗](#lib:operator%5b%5d,map_) `constexpr mapped_type& operator[](key_type&& x); ` [2](#access-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11826) *Effects*: Equivalent to: return try_emplace(std​::​move(x)).first->second; [🔗](#lib:operator%5b%5d,map__) `template constexpr mapped_type& operator[](K&& x); ` [3](#access-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11837) *Constraints*: The [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Compare​::​is_transparent is valid and denotes a type[.](#access-3.sentence-1) [4](#access-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11842) *Effects*: Equivalent to: return try_emplace(std​::​forward(x)).first->second; [🔗](#lib:at,map) `constexpr mapped_type& at(const key_type& x); constexpr const mapped_type& at(const key_type& x) const; ` [5](#access-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11854) *Returns*: A reference to the mapped_type corresponding to x in *this[.](#access-5.sentence-1) [6](#access-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11858) *Throws*: An exception object of type out_of_range if no such element is present[.](#access-6.sentence-1) [7](#access-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11863) *Complexity*: Logarithmic[.](#access-7.sentence-1) [🔗](#lib:at,map_) `template constexpr mapped_type& at(const K& x); template constexpr const mapped_type& at(const K& x) const; ` [8](#access-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11875) *Constraints*: The [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Compare​::​is_transparent is valid and denotes a type[.](#access-8.sentence-1) [9](#access-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11880) *Preconditions*: The expression find(x) is well-formed and has well-defined behavior[.](#access-9.sentence-1) [10](#access-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11884) *Returns*: A reference to find(x)->second[.](#access-10.sentence-1) [11](#access-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11888) *Throws*: An exception object of type out_of_range iffind(x) == end() is true[.](#access-11.sentence-1) [12](#access-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11893) *Complexity*: Logarithmic[.](#access-12.sentence-1) #### [23.4.3.4](#modifiers) Modifiers [[map.modifiers]](map.modifiers) [🔗](#lib:insert,map) `template constexpr pair insert(P&& x); template constexpr iterator insert(const_iterator position, P&& x); ` [1](#modifiers-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11909) *Constraints*: is_constructible_v is true[.](#modifiers-1.sentence-1) [2](#modifiers-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11913) *Effects*: The first form is equivalent toreturn emplace(std​::​forward

(x))[.](#modifiers-2.sentence-1) The second form is equivalent to return emplace_hint(position, std​::​forward

(x))[.](#modifiers-2.sentence-2) [🔗](#lib:try_emplace,map) `template constexpr pair try_emplace(const key_type& k, Args&&... args); template constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); ` [3](#modifiers-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11929) *Preconditions*: value_type is *Cpp17EmplaceConstructible* into map from piecewise_construct, forward_as_tuple(k),forward_as_tuple(std​::​forward(args)...)[.](#modifiers-3.sentence-1) [4](#modifiers-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11935) *Effects*: If the map already contains an element whose key is equivalent to k, there is no effect[.](#modifiers-4.sentence-1) Otherwise inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(k),forward_as_tuple(std​::​forward(args)...)[.](#modifiers-4.sentence-2) [5](#modifiers-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11944) *Returns*: In the first overload, the bool component of the returned pair is true if and only if the insertion took place[.](#modifiers-5.sentence-1) The returned iterator points to the map element whose key is equivalent to k[.](#modifiers-5.sentence-2) [6](#modifiers-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11952) *Complexity*: The same as emplace and emplace_hint, respectively[.](#modifiers-6.sentence-1) [🔗](#lib:try_emplace,map_) `template constexpr pair try_emplace(key_type&& k, Args&&... args); template constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); ` [7](#modifiers-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11967) *Preconditions*: value_type is *Cpp17EmplaceConstructible* into map from piecewise_construct, forward_as_tuple(std​::​move(k)),forward_as_tuple(std​::​forward(args)...)[.](#modifiers-7.sentence-1) [8](#modifiers-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11973) *Effects*: If the map already contains an element whose key is equivalent to k, there is no effect[.](#modifiers-8.sentence-1) Otherwise inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(std​::​move(k)),forward_as_tuple(std​::​forward(args)...)[.](#modifiers-8.sentence-2) [9](#modifiers-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11982) *Returns*: In the first overload, the bool component of the returned pair is true if and only if the insertion took place[.](#modifiers-9.sentence-1) The returned iterator points to the map element whose key is equivalent to k[.](#modifiers-9.sentence-2) [10](#modifiers-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11990) *Complexity*: The same as emplace and emplace_hint, respectively[.](#modifiers-10.sentence-1) [🔗](#lib:try_emplace,map__) `template constexpr pair try_emplace(K&& k, Args&&... args); template constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args); ` [11](#modifiers-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12005) *Constraints*: The [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Compare​::​is_transparent is valid and denotes a type[.](#modifiers-11.sentence-1) For the first overload,is_convertible_v andis_convertible_v are both false[.](#modifiers-11.sentence-2) [12](#modifiers-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12014) *Preconditions*: value_type is *Cpp17EmplaceConstructible* into map frompiecewise_construct, forward_as_tuple(std​::​forward(k)), forward_as_tuple(std​::​forward(args)...)[.](#modifiers-12.sentence-1) [13](#modifiers-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12020) *Effects*: If the map already contains an element whose key is equivalent to k, there is no effect[.](#modifiers-13.sentence-1) Otherwise, let r be equal_range(k)[.](#modifiers-13.sentence-2) Constructs an object u of type value_type withpiecewise_construct, forward_as_tuple(std​::​forward(k)), forward_as_tuple(std​::​forward(args)...)[.](#modifiers-13.sentence-3) If equal_range(u.first) == r is false, the behavior is undefined[.](#modifiers-13.sentence-4) Inserts u into *this[.](#modifiers-13.sentence-5) [14](#modifiers-14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12032) *Returns*: For the first overload, the bool component of the returned pair is true if and only if the insertion took place[.](#modifiers-14.sentence-1) The returned iterator points to the map element whose key is equivalent to k[.](#modifiers-14.sentence-2) [15](#modifiers-15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12040) *Complexity*: The same as emplace and emplace_hint, respectively[.](#modifiers-15.sentence-1) [🔗](#lib:insert_or_assign,map) `template constexpr pair insert_or_assign(const key_type& k, M&& obj); template constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); ` [16](#modifiers-16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12054) *Mandates*: is_assignable_v is true[.](#modifiers-16.sentence-1) [17](#modifiers-17) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12058) *Preconditions*: value_type is *Cpp17EmplaceConstructible* into map from k, std​::​forward(obj)[.](#modifiers-17.sentence-1) [18](#modifiers-18) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12063) *Effects*: If the map already contains an element e whose key is equivalent to k, assigns std​::​forward(obj) to e.second[.](#modifiers-18.sentence-1) Otherwise inserts an object of type value_type constructed with k, std​::​forward(obj)[.](#modifiers-18.sentence-2) [19](#modifiers-19) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12071) *Returns*: In the first overload, the bool component of the returned pair is true if and only if the insertion took place[.](#modifiers-19.sentence-1) The returned iterator points to the map element whose key is equivalent to k[.](#modifiers-19.sentence-2) [20](#modifiers-20) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12079) *Complexity*: The same as emplace and emplace_hint, respectively[.](#modifiers-20.sentence-1) [🔗](#lib:insert_or_assign,map_) `template constexpr pair insert_or_assign(key_type&& k, M&& obj); template constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); ` [21](#modifiers-21) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12094) *Mandates*: is_assignable_v is true[.](#modifiers-21.sentence-1) [22](#modifiers-22) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12098) *Preconditions*: value_type is *Cpp17EmplaceConstructible* into map from std​::​move(k), std​::​forward(obj)[.](#modifiers-22.sentence-1) [23](#modifiers-23) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12103) *Effects*: If the map already contains an element e whose key is equivalent to k, assigns std​::​forward(obj) to e.second[.](#modifiers-23.sentence-1) Otherwise inserts an object of type value_type constructed with std​::​​move(k), std​::​forward(obj)[.](#modifiers-23.sentence-2) [24](#modifiers-24) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12111) *Returns*: In the first overload, the bool component of the returned pair is true if and only if the insertion took place[.](#modifiers-24.sentence-1) The returned iterator points to the map element whose key is equivalent to k[.](#modifiers-24.sentence-2) [25](#modifiers-25) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12119) *Complexity*: The same as emplace and emplace_hint, respectively[.](#modifiers-25.sentence-1) [🔗](#lib:insert_or_assign,map__) `template constexpr pair insert_or_assign(K&& k, M&& obj); template constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); ` [26](#modifiers-26) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12134) *Constraints*: The [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Compare​::​is_transparent is valid and denotes a type[.](#modifiers-26.sentence-1) [27](#modifiers-27) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12139) *Mandates*: is_assignable_v is true[.](#modifiers-27.sentence-1) [28](#modifiers-28) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12143) *Preconditions*: value_type is *Cpp17EmplaceConstructible* into map fromstd​::​forward(k), std​::​ forward(obj)[.](#modifiers-28.sentence-1) [29](#modifiers-29) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12148) *Effects*: If the map already contains an element e whose key is equivalent to k, assigns std​::​forward (obj) to e.second[.](#modifiers-29.sentence-1) Otherwise, let r be equal_range(k)[.](#modifiers-29.sentence-2) Constructs an object u of type value_type with std​::​forward(k), std​::​forward(obj)[.](#modifiers-29.sentence-3) If equal_range(u.first) == r is false, the behavior is undefined[.](#modifiers-29.sentence-4) Inserts u into *this[.](#modifiers-29.sentence-5) [30](#modifiers-30) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12160) *Returns*: For the first overload, the bool component of the returned pair is true if and only if the insertion took place[.](#modifiers-30.sentence-1) The returned iterator points to the map element whose key is equivalent to k[.](#modifiers-30.sentence-2) [31](#modifiers-31) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12168) *Complexity*: The same as emplace and emplace_hint, respectively[.](#modifiers-31.sentence-1) #### [23.4.3.5](#erasure) Erasure [[map.erasure]](map.erasure) [🔗](#lib:erase_if,map) `template typename map::size_type constexpr erase_if(map& c, Predicate pred); ` [1](#erasure-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12183) *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();