Is there any particular reason why heterogeneous version of erase
in associative containers (std::map
, std::unordered_map
, std::multimap
and std::unordered_multimap
) takes in a forwarding reference and all other heterogeneous functions (find
/equal_range
, count
, contains
) take in const-reference?
For instance in case of std::unordered_map
:
template<class K> iterator find(const K& k);
template<class K> const_iterator find(const K& k) const;
template<class K> size_type erase(K&& x);
https://en.cppreference.com/w/cpp/container/unordered_map/erase (overload 4) https://en.cppreference.com/w/cpp/container/unordered_map/find (overloads 3/4)
Section 24.5.4.1 of (lastest working draft) n4910
(This, as mentioned, applies to other containers as well.)
After doing a bit more research I've found the original proposal p2077 which explains it (paragraphs 2 and 3.1).
If the overload
template <class K>
size_type erase( const K& x );
existed, it would be chosen when passing an object of a type, which is implicitly convertible to either iterator
or const_iterator
and that is not what users might expect.
Additionally it is not possible to create a valid constraints for the mentioned overload because the value category of K
is lost due to template argument deduction from const K&
function parameter. Therefore, we cannot define constraints over K
for the arbitrary case. To propagate the information about the value category of K
we define the function parameter for heterogeneous erasure as forwarding reference.
A more detailed explanation can be found in proposal.