This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
Section: 23.2.7.1 [associative.reqmts.general], 23.4.3.4 [map.modifiers], 23.4.6.4 [set.modifiers] Status: New Submitter: Joaquin M López Muñoz Opened: 2026-04-19 Last modified: 2026-04-20
Priority: Not Prioritized
View other active issues in [associative.reqmts.general].
View all other issues in [associative.reqmts.general].
View all issues with New status.
Discussion:
23.2.7.1 [associative.reqmts.general] mandates that Compare induce a strict weak
ordering (SWO) on elements of Key. A strict reading of this requirement without further
qualifications implies, for instance, that using a container such as std::set<double>
is UB regardless of what elements go into it (because std::less<double> is
not a SWO on all values of double due to NaN). Assuming that the intent of the
standard is to allow for the use of std::set<double> and other containers
where Compare does not induce a full SWO on all possible values of Key, there are
(at least) two possible relaxations of the original requirement:
Let K be the set of keys in an associative container a at a given point in time:
Compare induces a SWO on K and also on {k} ∪ K for any k involved in an attempted
insertion into a (either successful or not).
Compare induces a SWO on K and also on {k} ∪ K for any k involved in an attempted
insertion (either successful or not) or a lookup operation.
Now, consider the following code:
// (A)
std::set<double> s = {0.0, 1.0, 2.0, 3.0};
auto nan = std::numeric_limits<double>::quiet_NaN();
return s.upper_bound(nan) == s.end();
Under interpretation 1, (A) is correct and returns true, whereas under interpretation 2
the code is UB because std::less<double> does not induce a SWO on
{0.0, 1.0, 2.0, 3.0, NaN}.
false.
See this godbolt link, where the different
behaviors are shown side by side.
Note, however, that the following pieces of code are not UB:
// (B) Global binary search functions
std::vector<double> v = {0.0, 3.0, 2.0, 1.0};
std::sort(v.begin(), v.end());
return std::upper_bound(v.begin(), v.end(), nan) == v.end(); // returns true
// (C) Heterogeneous lookup
std::set<double, std::less<>> s = {0.0, 1.0, 2.0, 3.0};
return s.upper_bound(std::cref(nan)) == s.end(); // returns true
because upper_bound in (B) and (C) only requires that the passed key
partition the range where lookup happens, and ¬( · < NaN) partitions
the range R = [0.0, 1.0, 2.0, 3.0] into R and []
(see upper.bound and
23.2.7.1 [associative.reqmts.general]/167.
The fact that (C) is well defined is an argument against interpretation 2,
given that (C) can be seen as a mere syntactic variation of (A).
Compare must induce a full SWO on all possible values of Key)
is unacceptably strict and hardly the intent of the standard. As reasonable interpretation
is left open, we're beginning to see observable divergences between C++ standard
library implementations.
Arguments in favor of partition-based lookup semantics
We posit that interpretation 1, supplemented with partition-based requirements for
non-heterogeneous lookup:
Let K be the set of keys in an associative container a at a given point in time:
Compare induces a SWO on K and also on {k} ∪ K for any k involved in an attempted
insertion into a (either successful or not). Non-heterogeneous lookup for k only requires
that k partition the range [a.begin(), a.end()).
is the most useful and reasonable interpretation. Some arguments in favor of this thesis:
Partition-based lookup semantics is maximally aligned and consistent with current requirements for global lookup algorithms and associative container heterogeneous lookup. In particular:
It makes (A) and (C) equivalent, which is a reasonable assumption any non-expert user could make.
It makes flat container adaptors truly equivalent to the manually-sorted vectors they are meant to replace:
// (D)
std::vector<double> v = {3.0, 1.0, 0.0, 2.0};
std::sort(v.begin(), v.end());
auto nan = std::numeric_limits<double>::quiet_NaN();
return std::upper_bound(v.begin(), v.end(), nan) == v.end();
// (E) only well defined and equivalent to (D) if partition-based lookup is adopted
std::flat_set<double> s = {3.0, 1.0, 0.0, 2.0};
auto nan = std::numeric_limits<double>::quiet_NaN();
return s.upper_bound(nan) == s.end();
In the N1313 foundational paper where partition-based semantics was first introduced, David Abrahams states that "[s]trict weak ordering is a great concept for sorting, but maybe it's not appropriate for searching".
N1313 informed the resolution of LWG 270(i) ("Binary search requirements overly strict"), whose rationale states that "[t]he proposed resolution reinterprets binary search. Instead of thinking about searching for a value in a sorted range, we view that as an important special case of a more general algorithm: searching for the partition point in a partitioned range".In N2882 and N3465, early versions of the paper upon which heterogeneous lookup for associative containers was defined (N3657), the wording for non-heterogeneous lookup was indeed partition-based in accordance with Abrahams's conceptual setup (though this exact wording didn't make it into the standard as is, for reasons unknown to the author).
For a unique associative container a, if Compare induces a strict partial order
on all its possible key values, then partition-based lookup is well defined everywhere.
Formally, if Compare is a SPO and a set K of keys is totally ordered wrt Compare
(i.e., K is a chain,
which the range [a.begin(), a.end()) always satisfies), then K is partitioned by any
arbitrary k (proof trivial).
Beyond admittedly corner cases such as that of NaN, there are partial orders that
directly benefit from partition-based semantics. For instance, if we have a set s
of non-overlapping interval objects ordered by their natural
interval order (such
as supported by
Boost.ICL, then s.equal_range(i) simply returns the range of intervals in s
that are contained in i. Boost.ICL, in fact, implicitly relies on the interpretation
of lookup semantics we're proposing here.
On a related note, it may be worth mentioning that the standard text has some general formulation
problems regarding the extent of applicability of semantic requirements (both for C++20
concepts and pre-C++20 well-defined expression tables, collectively called named requirements).
16.3.2.3 [structure.requirements]/8 tries to provide some leeway for the specific case
of concepts in a manner described by P2027R0, section "This is a special
case of a much bigger problem", as "little more than handwaving".
Proposed resolution:
This wording is relative to N5032.
Modify 23.2.7.1 [associative.reqmts.general] as indicated:
-2- Each associative container is parameterized on
[…] -7- In this subclause,Keyand an ordering relationComparethat induces a strict weak ordering (26.8 [alg.sorting]) onelements ofthe values ofKeyKeyin the container at any point in time. In addition,mapandmultimapassociate an arbitrary mapped typeTwith theKey. The object of typeCompareis called the comparison object of a container.
(7.1) —
Xdenotes an associative container class,[…]
(7.7) —
a_eqdenotes a value of typeXwhenXsupports equivalent keys,
(7.8) —a_trandenotes a value of typeXorconst Xwhen the qualified-idX::key_compare::is_transparentis valid and denotes a type (13.10.3 [temp.deduct]),(7.9) —
iandjmeet the Cpp17InputIterator requirements and refer to elements implicitly convertible tovalue_type,[…]
(7.17) —
tdenotes a value of typeX::value_type, and
(7.18) —kdenotes a value of typeX::key_type, and(7.19) —
cdenotes a value of typeX::key_compareorconst X::key_compare;[…]
(7.23) —
kxis a value such that
(7.23.1) —
ais partitioned with respect toc(x, kx)and!c(kx, x), withc(x, kx)implying!c(kx, x)and withxthe key value ofeandeina, and(7.23.2) —
kxis not convertible to eitheriteratororconst_iterator;and(7.23.?) — if qualified-id
X::key_compare::is_transparentis not valid or does not denote a type (13.10.3 [temp.deduct]), thenkl,ku,keandkxare of typeX::key_type;[…]
[…]
[…]a_uniq.emplace(args)-47- Result:
-48- Preconditions:pair<iterator, bool>value_typeis Cpp17EmplaceConstructible intoXfromargs. Iftis avalue_typeobject constructed withstd::forward<Args>(args)...,Compareinduces a strict weak ordering on the set of values comprising the key oftand all the keys ina_uniq. -49- Effects: Inserts avalue_typeobjecttconstructed withstd::forward<Args>(args)...if and only if there is no element in the container with key equivalent to the key oft. -50- Returns: Theboolcomponent of the returned pair istrueif and only if the insertion takes place, and the iterator component of the pair points to the element with key equivalent to the key oft. -51- Complexity: Logarithmic.a_eq.emplace(args)[…]-52- Result:
-53- Preconditions:iteratorvalue_typeis Cpp17EmplaceConstructible intoXfromargs. Iftis avalue_typeobject constructed withstd::forward<Args>(args)...,Compareinduces a strict weak ordering on the set of values comprising the key oftand all the keys ina_eq. -54- Effects: Inserts avalue_typeobjecttconstructed withstd::forward<Args>(args)....If a range containing elements equivalent totexists ina_eq,tis inserted at the end of that range. -55- Returns: An iterator pointing to the newly inserted element. -56- Complexity: Logarithmic.a_uniq.insert(t)-61- Result:
-62- Preconditions: Ifpair<iterator, bool>tis a non-const rvalue,value_typeis Cpp17MoveInsertable intoX; otherwise,value_typeis Cpp17CopyInsertable intoX.Compareinduces a strict weak ordering on the set of values comprising the key oftand all the keys ina_uniq. -63- Effects: Insertstif and only if there is no element in the container with key equivalent to the key oft. -64- Returns: Theboolcomponent of the returned pair istrueif and only if the insertion takes place, and the iterator component of the pair points to the element with key equivalent to the key oft. -65- Complexity: Logarithmic.a_eq.insert(t)-66- Result:
-67- Preconditions: Ifiteratortis a non-const rvalue,value_typeis Cpp17MoveInsertable intoX; otherwise,value_typeis Cpp17CopyInsertable intoX.Compareinduces a strict weak ordering on the set of values comprising the key oftand all the keys ina_eq. -68- Effects: Insertstand returns the iterator pointing to the newly inserted element. If a range containing elements equivalent totexists ina_eq,tis inserted at the end of that range. -69- Complexity: Logarithmic.a.insert(p, t)-70- Result:
-71- Preconditions: Ifiteratortis a non-const rvalue,value_typeis Cpp17MoveInsertable intoX; otherwise,value_typeis Cpp17CopyInsertable intoX.Compareinduces a strict weak ordering on the set of values comprising the key oftand all the keys ina. -72- Effects: Insertstif and only if there is no element with key equivalent to the key oftin containers with unique keys; always insertstin containers with equivalent keys.tis inserted as close as possible to the position just prior top. -73- Returns: An iterator pointing to the element with key equivalent to the key oft. -74- Complexity: Logarithmic in general, but amortized constant iftis inserted right beforep.a.insert(i, j)-75- Result:
-76- Preconditions:voidvalue_typeis Cpp17EmplaceConstructible intoXfrom*i. Neitherinorjare iterators intoa.Compareinduces a strict weak ordering on the set of values comprising all the keys in[i, j)and all the keys ina. -77- Effects: Inserts each element from the range[i, j)if and only if there is no element with key equivalent to the key of that element in containers with unique keys; always inserts that element in containers with equivalent keys. -78- Complexity:Nlog(a.size() + N), whereNhas the valuedistance(i, j).a.insert_range(rg)[…]-79- Result:
-80- Preconditions:voidvalue_typeis Cpp17EmplaceConstructible intoXfrom*ranges::begin(rg).rgandado not overlap.Compareinduces a strict weak ordering on the set of values comprising all the keys inrgand all the keys ina. -81- Effects: Inserts each element fromrgif and only if there is no element with key equivalent to the key of that element in containers with unique keys; always inserts that element in containers with equivalent keys. -82- Complexity:Nlog(a.size() + N), whereNhas the valueranges::distance(rg).a_uniq.insert(nh)-84- Result:
-85- Preconditions:insert_return_typenhis empty ora_uniq.get_allocator() == nh.get_allocator()istrue. Ifnhis not empty,Compareinduces a strict weak ordering on the set of values comprising the key ofnhand all the keys ina_uniq. -86- Effects: Ifnhis empty, has no effect. Otherwise, inserts the element owned bynhif and only if there is no element in the container with a key equivalent tonh.key(). -87- Returns: Ifnhis empty, inserted isfalse,positionisend(), andnodeis empty. Otherwise if the insertion took place,insertedistrue,positionpoints to the inserted element, andnodeis empty; if the insertion failed,insertedisfalse,nodehas the previous value ofnh, andpositionpoints to an element with a key equivalent tonh.key(). -88- Complexity: Logarithmic.a_eq.insert(nh)-89- Result:
-90- Preconditions:iteratornhis empty ora_eq.get_allocator() == nh.get_allocator()istrue. Ifnhis not empty,Compareinduces a strict weak ordering on the set of values comprising the key ofnhand all the keys ina_eq. -91- Effects: Ifnhis empty, has no effect and returnsa_eq.end(). Otherwise, inserts the element owned bynhand returns an iterator pointing to the newly inserted element. If a range containing elements with keys equivalent tonh.key()exists ina_eq, the element is inserted at the end of that range. -92- Postconditions:nhis empty. -93- Complexity: Logarithmic.a.insert(p, nh)[…]-94- Result:
-95- Preconditions:iteratornhis empty ora.get_allocator() == nh.get_allocator()istrue. Ifnhis not empty,Compareinduces a strict weak ordering on the set of values comprising the key ofnhand all the keys ina. -96- Effects: Ifnhis empty, has no effect and returnsa.end(). Otherwise, inserts the element owned bynhif and only if there is no element with key equivalent tonh.key()in containers with unique keys; always inserts the element owned bynhin containers with equivalent keys. The element is inserted as close as possible to the position just prior top. -97- Postconditions:nhis empty if insertion succeeds, unchanged if insertion fails. -98- Returns: An iterator pointing to the element with key equivalent tonh.key(). -99- Complexity: Logarithmic.a.extract(k)
-100- Result:node_type-101- Effects: Removes the first element in the container with key equivalent tok.-102- Returns: Anode_typeowning the element if found, otherwise an emptynode_type.-103- Complexity: log(a.size())a_trana.extract(kx)[…]-104- Result:
-105- Effects: Removes the first element in the container with keynode_typersuch that!c(r, kx) && !c(kx, r)istrue. -106- Returns: Anode_typeowning the element if found, otherwise an emptynode_type. -107- Complexity: log()a_trana.size()a.merge(a2)-112- Result:
-113- Preconditions:voida.get_allocator() == a2.get_allocator()istrue.Compareinduces a strict weak ordering on the set of values comprising all the keys inaand all the keys ina2. -114- Effects: Attempts to extract each element ina2and insert it intoausing the comparison object ofa. In containers with unique keys, if there is an element in a with key equivalent to the key of an element froma2, then that element is not extracted froma2. -115- Postconditions: Pointers and references to the transferred elements ofa2refer to those same elements but as members ofa. Ifa.begin()anda2.begin()have the same type, iterators referring to the transferred elements will continue to refer to their elements, but they now behave as iterators intoa, not intoa2. -116- Throws: Nothing unless the comparison object throws. -117- Complexity:Nlog(a.size()+N), whereNhas the valuea2.size().a.erase(k)
-118- Result:size_type-119- Effects: Erases all elements in the container with key equivalent tok.-120- Returns: The number of erased elements.-121- Complexity: log(a.size()) +a.count(k)a_trana.erase(kx)[…]-122- Result:
-123- Effects: Erases all elements in the container with keysize_typersuch that!c(r, kx) && !c(kx, r)istrue. -124- Returns: The number of erased elements. -125- Complexity: log() +a_trana.size()a_trana.count(kx)b.find(k)
-141- Result:iterator;const_iteratorfor constantb.-142- Returns: An iterator pointing to an element with the key equivalent tok, orb.end()if such an element is not found.-143- Complexity: Logarithmic.a_tranb.find(ke)-144- Result:
-145- Returns: An iterator pointing to an element with keyiterator;const_iteratorfor constant.a_tranbrsuch that!c(r, ke) && !c(ke, r)istrue, orif such an element is not found. -146- Complexity: Logarithmic.a_tranb.end()b.count(k)
-147- Result:size_type-148- Returns: The number of elements with key equivalent tok.-149- Complexity: log(b.size()) +b.count(k)a_tranb.count(ke)-150- Result:
-151- Returns: The number of elements with keysize_typersuch that!c(r, ke) && !c(ke, r). -152- Complexity: log() +a_tranb.size()a_tranb.count(ke)b.contains(k)
-153- Result:bool-154- Effects: Equivalent to:return b.find(k) != b.end();a_tranb.contains(ke)-155- Result:
-156- Effects: Equivalent to:boolreturna_tranb.find(ke) !=a_tranb.end();b.lower_bound(k)
-157- Result:iterator;const_iteratorfor constantb.-158- Returns: An iterator pointing to the first element with key not less thank, orb.end()if such an element is not found.-159- Complexity: Logarithmic.a_tranb.lower_bound(kl)-160- Result:
-161- Returns: An iterator pointing to the first element with keyiterator;const_iteratorfor constant.a_tranbrsuch that !c(r, kl), orif such an element is not found. -162- Complexity: Logarithmic.a_tranb.end()b.upper_bound(k)
-163- Result:iterator;const_iteratorfor constantb.-164- Returns: An iterator pointing to the first element with key greater thank, orb.end()if such an element is not found.-165- Complexity: Logarithmic.a_tranb.upper_bound(ku)-166- Result:
-167- Returns: An iterator pointing to the first element with keyiterator;const_iteratorfor constant.a_tranbrsuch thatc(ku, r), orif such an element is not found. -168- Complexity: Logarithmic.a_tranb.end()b.equal_range(k)
-169- Result:pair<iterator, iterator>;pair<const_iterator, const_iterator>for constantb.-170- Effects: Equivalent to:return make_pair(b.lower_bound(k), b.upper_bound(k));-171- Complexity: Logarithmic.a_tranb.equal_range(ke)-172- Result:
-173- Effects: Equivalent to:pair<iterator, iterator>;pair<const_iterator, const_iterator>for constant.a_tranbreturn make_pair(-174- Complexity: Logarithmic.a_tranb.lower_bound(ke),a_tranb.upper_bound(ke));
Modify 23.2.7.2 [associative.reqmts.except] as indicated:
-1- For associative containers, no
clear()function throws an exception.erase(does not throw an exception unless that exception is thrown by the container'skkx)Compareobject (if any).
Modify 23.4.3.4 [map.modifiers] as indicated:
template<class... Args> constexpr pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); template<class... Args> constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);-3- Preconditions:
-4- Effects: If the map already contains an element whose key is equivalent tovalue_typeis Cpp17EmplaceConstructible intomapfrompiecewise_construct,forward_as_tuple(k),forward_as_tuple(std::forward<Args>(args)...).Compareinduces a strict weak ordering on the set of values comprisingkand all the keys in*this.k, there is no effect. Otherwise inserts an object of typevalue_typeconstructed withpiecewise_construct,forward_as_tuple(k),forward_as_tuple(std::forward<Args>(args)...). -5- Returns: In the first overload, theboolcomponent of the returned pair istrueif and only if the insertion took place. The returned iterator points to the map element whose key is equivalent tok. -6- Complexity: The same asemplaceandemplace_hint, respectively.template<class... Args> constexpr pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); template<class... Args> constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);-7- Preconditions:
-8- Effects: If the map already contains an element whose key is equivalent tovalue_typeis Cpp17EmplaceConstructible intomapfrompiecewise_construct,forward_as_tuple(std::move(k)),forward_as_tuple(std::forward<Args>(args)...).Compareinduces a strict weak ordering on the set of values comprisingkand all the keys in*this.k, there is no effect. Otherwise inserts an object of typevalue_typeconstructed withpiecewise_construct,forward_as_tuple(std::move(k)),forward_as_tuple(std::forward<Args>(args)...). -9- Returns: In the first overload, theboolcomponent of the returned pair istrueif and only if the insertion took place. The returned iterator points to the map element whose key is equivalent tok. -10- Complexity: The same asemplaceandemplace_hint, respectively.template<class K, class... Args> constexpr pair<iterator, bool> try_emplace(K&& k, Args&&... args); template<class K, class... Args> constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args);-11- Constraints: The qualified-id
-12- Preconditions:Compare::is_transparentis valid and denotes a type. For the first overload,is_convertible_v<K&&, const_iterator>andis_convertible_v<K&&, iterator>are bothfalse.value_typeis Cpp17EmplaceConstructible intomapfrompiecewise_construct,forward_as_tuple(std::forward<K>(k)),forward_as_tuple(std::forward<Args>(args)...).Compareinduces a strict weak ordering on the set of values comprisingkey_type(std::forward<K>(k))and all the keys in*this. -13- Effects: If the map already contains an element whose key is equivalent tok, there is no effect. Otherwise, letrbeequal_range(k). Constructs an objectuof typevalue_typewithpiecewise_construct,forward_as_tuple(std::forward<K>(k)),forward_as_tuple(std::forward<Args>(args)...). Ifequal_range(u.first) == risfalse, the behavior is undefined. Insertsuinto*this. -14- Returns: In the first overload, theboolcomponent of the returned pair istrueif and only if the insertion took place. The returned iterator points to the map element whose key is equivalent tok. -15- Complexity: The same asemplaceandemplace_hint, respectively.template<class M> constexpr pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); template<class M> constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);-16- Mandates:
-17- Preconditions:is_assignable_v<mapped_type&, M&&>istrue.value_typeis Cpp17EmplaceConstructible intomapfromk,std::forward<M>(obj).Compareinduces a strict weak ordering on the set of values comprisingkand all the keys in*this. -18- Effects: If the map already contains an elementewhose key is equivalent tok, assignsstd::forward<M>(obj)toe.second. Otherwise inserts an object of typevalue_typeconstructed withk,std::forward<M>(obj). -19- Returns: In the first overload, theboolcomponent of the returned pair istrueif and only if the insertion took place. The returned iterator points to the map element whose key is equivalent tok. -20- Complexity: The same asemplaceandemplace_hint, respectively.template<class M> constexpr pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); template<class M> constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);-21- Mandates:
-22- Preconditions:is_assignable_v<mapped_type&, M&&>istrue.value_typeis Cpp17EmplaceConstructible intomapfromstd::move(k),std::forward<M>(obj).Compareinduces a strict weak ordering on the set of values comprisingkand all the keys in*this. -23- Effects: If the map already contains an elementewhose key is equivalent tok, assignsstd::forward<M>(obj)toe.second. Otherwise inserts an object of typevalue_typeconstructed withstd::move(k),std::forward<M>(obj). -24- Returns: In the first overload, theboolcomponent of the returned pair istrueif and only if the insertion took place. The returned iterator points to the map element whose key is equivalent tok. -25- Complexity: The same asemplaceandemplace_hint, respectively.-26- Constraints:
-27- Mandates:is_assignable_v<mapped_type&, M&&>istrue.is_assignable_v<mapped_type&, M&&>istrue. -28- Preconditions:value_typeis Cpp17EmplaceConstructible intomapfromstd::forward<K>(k),std::forward<M>(obj).Compareinduces a strict weak ordering on the set of values comprisingkand all the keys in*this. -29- Effects: If the map already contains an elementewhose key is equivalent tok, assignsstd::forward<M>(obj)toe.second. Otherwise, letrbeequal_range(k). Constructs an objectuof typevalue_typewithstd::forward<K>(k),std::forward<M>(obj). Ifequal_range(u.first) == risfalse, the behavior is undefined. Insertsuinto*this. -30- Returns: In the first overload, theboolcomponent of the returned pair istrueif and only if the insertion took place. The returned iterator points to the map element whose key is equivalent tok. -31- Complexity: The same asemplaceandemplace_hint, respectively.
Modify 23.4.6.4 [set.modifiers] as indicated:
template<class K> constexpr pair<iterator, bool> insert(K&& x); template<class K> constexpr iterator insert(const_iterator hint, K&& x);-1- Constraints: The qualified-id
-2- Preconditions:Compare::is_transparentis valid and denotes a type. For the second overload,is_convertible_v<K&&, const_iterator>andis_convertible_v<K&&, iterator>are bothfalse.value_typeis Cpp17EmplaceConstructible intosetfromstd::forward<K>(x).Compareinduces a strict weak ordering on the set of values comprisingkand all the keys in*this. -3- Effects: If the set already contains an element that is equivalent tox, there is no effect. Otherwise, letrbeequal_range(x). Constructs an objectuof typevalue_typewithstd::forward<K>(x). Ifequal_range(u) == risfalse, the behavior is undefined. Insertsuinto*this. -4- Returns: In the first overload, theboolcomponent of the returned pair istrueif and only if the insertion took place. The returned iterator points to the set element that is equivalent tox. -5- Complexity: Logarithmic.