为什么关联容器的擦除的异构版本需要转发引用?

Mar*_*zek 5 c++ language-design c++23

erase关联容器中的异构版本(std::mapstd::unordered_map和)采用转发引用而所有其他异构函数(/ 、、)采用常量引用,std::multimap是否有任何特殊原因?std::unordered_multimapfindequal_rangecountcontains

例如在以下情况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);
Run Code Online (Sandbox Code Playgroud)

https://en.cppreference.com/w/cpp/container/unordered_map/erase(重载 4) https://en.cppreference.com/w/cpp/container/unordered_map/find(重载 3/4)

(最新工作草案) n4910第 24.5.4.1 节

(如上所述,这也适用于其他容器。)

Mar*_*zek 4

经过更多研究后,我发现了原始提案p2077对此进行了解释(第 2 和 3.1 段)。

如果超载

template <class K>
size_type erase( const K& x );
Run Code Online (Sandbox Code Playgroud)

存在,当传递一个类型的对象时会选择它,该类型可以隐式转换为 or ,iteratorconst_iterator这不是用户所期望的。

此外,不可能为提到的重载创建有效的约束,因为由于从函数参数K推导模板参数,导致 的值类别丢失。因此,我们不能为任意情况const K&定义约束。K为了传播有关值类别的信息,K我们定义异构擦除的函数参数作为转发参考。

更详细的解释可以在提案中找到。