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.
The issue LWG 2059 was reported and resolved in C++17 by adding an extra overload for 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.
Consequently, this issue can be resolved in the same way as for std::map::erase by adding an overload for extract which accepts iterator as an argument.