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.
3227. Ambiguity issue forextract
in ordered and unordered associative containers
Section: 23.2.7 [associative.reqmts], 23.2.8 [unord.req] Status: New Submitter: Konstantin Boyarinov Opened: 2019-06-25 Last modified: 2022-04-24
Priority: 3
View other active issues in [associative.reqmts].
View all other issues in [associative.reqmts].
View all issues with New status.
Discussion:
Ordered and unordered associative containers in C++14 contained an issue, which caused an ambiguity while invoking std::map::erase
when key_type
of the map can be constructed from the iterator. In this case both overloads erase(const key_type&)
and erase(const_iterator)
could be chosen.
erase
in ordered and unordered associative containers which accepts iterator
as an argument. C++17 also introduced new functionality for splicing ordered and unordered maps and sets. One of the extensions allows to extract a node from the container by passing either key_type&
or const_iterator
to the extract()
member function:
node_type extract(const key_type& x); node_type extract(const_iterator position);
Providing these two extract
overloads causes the same problem as for erase
. Consider the following example:
#include <map> #include <string> struct Key { template <typename T> Key(const T&) {} }; bool operator<(const Key&, const Key&) { return false; } int main() { using map_type = std::map<Key, std::string>; map_type m({ {Key(1), "a"}, {Key(2), "b"} }); map_type::iterator it = m.begin(); auto nh = m.extract(it); }
In this case, call to extract()
is ambiguous, because the overloads which accept const_iterator
and key_type
are equally good matches for the argument it
.
std::map::erase
by adding an overload for extract
which accepts iterator
as an argument.
[2019-07 Issue Prioritization]
Priority to 3 after discussion on the reflector.
Previous resolution [SUPERSEDED]:
This wording is relative to N4820.
Modify [tab:container.assoc.req], Table 69 — "Associative container requirements", as indicated:
Table 69 — Associative container requirements (in addition to container) [tab:container.assoc.req] Expression Return type Assertion/note pre-/post-condition Complexity…
a.extract(q)
node_type
Effects: Removes the element
pointed to byq
.
Returns: Anode_type
owning
that element. amortized constanta.extract(r)
node_type
Effects: Removes the element
pointed to byr
.
Returns: Anode_type
owning
that element. amortized constant…
Modify [tab:container.assoc.req], Table 70 — "Unordered associative container requirements", as indicated:
Table 70 — Unordered associative container requirements (in addition to container) [tab:container.hash.req] Expression Return type Assertion/note pre-/post-condition Complexity…
a.extract(q)
node_type
Effects: Removes the element
pointed to byq
.
Returns: Anode_type
owning
that element. Average case𝒪(1)
, worst case𝒪(a.size())
.a.extract(r)
node_type
Effects: Removes the element
pointed to byr
.
Returns: Anode_type
owning
that element. Average case𝒪(1)
, worst case𝒪(a.size())
.…
Modify 23.4.3.1 [map.overview], class template
map
synopsis, as indicated:[…] node_type extract(iterator position); node_type extract(const_iterator position); node_type extract(const key_type& x); […]Modify 23.4.4.1 [multimap.overview], class template
multimap
synopsis, as indicated:[…] node_type extract(iterator position); node_type extract(const_iterator position); node_type extract(const key_type& x); […]Modify 23.4.6.1 [set.overview], class template
set
synopsis, as indicated:[…] node_type extract(iterator position); node_type extract(const_iterator position); node_type extract(const key_type& x); […]Modify 23.4.7.1 [multiset.overview], class template
multiset
synopsis, as indicated:[…] node_type extract(iterator position); node_type extract(const_iterator position); node_type extract(const key_type& x); […]Modify 23.5.3.1 [unord.map.overview], class template
unordered_map
synopsis, as indicated:[…] node_type extract(iterator position); node_type extract(const_iterator position); node_type extract(const key_type& x); […]Modify 23.5.4.1 [unord.multimap.overview], class template
unordered_multimap
synopsis, as indicated:[…] node_type extract(iterator position); node_type extract(const_iterator position); node_type extract(const key_type& x); […]Modify 23.5.6.1 [unord.set.overview], class template
unordered_set
synopsis, as indicated:[…] node_type extract(iterator position); node_type extract(const_iterator position); node_type extract(const key_type& x); […]Modify 23.5.7.1 [unord.multiset.overview], class template
unordered_multiset
synopsis, as indicated:[…] node_type extract(iterator position); node_type extract(const_iterator position); node_type extract(const key_type& x); […]
[2022-04-24; Daniel rebases wording on N4910]
Proposed resolution:
This wording is relative to N4910.
Modify 23.2.7.1 [associative.reqmts.general] as indicated:
a.extract(q)-108- Result:
-109- Effects: Removes the element pointed to bynode_type
q
. -110- Returns: Anode_type
owning that element. -111- Complexity: Amortized constant.a.extract(r)-?- Result:
-?- Effects: Removes the element pointed to bynode_type
r
. -?- Returns: Anode_type
owning that element. -?- Complexity: Amortized constant.
Modify 23.2.8.1 [unord.req.general] as indicated:
a.extract(q)-141- Result:
-142- Effects: Removes the element pointed to bynode_type
q
. -143- Returns: Anode_type
owning that element. -144- Complexity: Average case𝒪(1)
, worst case𝒪(a.size())
.a.extract(r)-?- Result:
-?- Effects: Removes the element pointed to bynode_type
r
. -?- Returns: Anode_type
owning that element. -?- Complexity: Average case𝒪(1)
, worst case𝒪(a.size())
.
Modify 23.4.3.1 [map.overview], class template map
synopsis, as indicated:
[…] node_type extract(iterator position); node_type extract(const_iterator position); node_type extract(const key_type& x); […]
Modify 23.4.4.1 [multimap.overview], class template multimap
synopsis, as indicated:
[…] node_type extract(iterator position); node_type extract(const_iterator position); node_type extract(const key_type& x); […]
Modify 23.4.6.1 [set.overview], class template set
synopsis, as indicated:
[…] node_type extract(iterator position); node_type extract(const_iterator position); node_type extract(const key_type& x); […]
Modify 23.4.7.1 [multiset.overview], class template multiset
synopsis, as indicated:
[…] node_type extract(iterator position); node_type extract(const_iterator position); node_type extract(const key_type& x); […]
Modify 23.5.3.1 [unord.map.overview], class template unordered_map
synopsis, as indicated:
[…] node_type extract(iterator position); node_type extract(const_iterator position); node_type extract(const key_type& x); […]
Modify 23.5.4.1 [unord.multimap.overview], class template unordered_multimap
synopsis, as indicated:
[…] node_type extract(iterator position); node_type extract(const_iterator position); node_type extract(const key_type& x); […]
Modify 23.5.6.1 [unord.set.overview], class template unordered_set
synopsis, as indicated:
[…] node_type extract(iterator position); node_type extract(const_iterator position); node_type extract(const key_type& x); […]
Modify 23.5.7.1 [unord.multiset.overview], class template unordered_multiset
synopsis, as indicated:
[…] node_type extract(iterator position); node_type extract(const_iterator position); node_type extract(const key_type& x); […]
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4