c++ 为什么关联容器有一个带非常量迭代器参数的擦除重载?

2guxujil  于 2023-05-02  发布在  其他
关注(0)|答案(1)|浏览(109)

C11将std::vector::erase改为const_iterator,而不是iterator。同样的事情也适用于std::dequestd::list,而std::forward_list在C11中带有erase_after,它也需要const_iterator
相比之下,std::set::erase保留了它的iterator重载,C11只是添加了const_iterator重载。这同样适用于所有关联容器:std::mapstd::multisetstd::multimap都保留了C11之前的iterator重载,而std::unordered_setstd::unordered_mapstd::unordered_multisetstd::unordered_multimap都是通过iteratorconst_iterator重载引入的。
事实上,对于所有四个集合类,iterator and const_iterator may very well be the same type
为什么会有差异?除了与非关联容器的不一致之外,范围擦除重载也存在不一致,它们都在C++11中被更改为采用一对const_iterator s而不是一对iterator s。由于iterator必须可转换为const_iterator,因此无需为范围擦除设置所有四种可能的参数组合。类似地,对于单值擦除,不需要“所有两个组合”,那么为什么要保持iterator过载呢?

hfwmuf9z

hfwmuf9z1#

最初在C11中,旧的iterator重载被所有这些容器的const_iterator重载所取代。
然而,关联容器总是有额外的erase重载,它们将键类型作为参数。像std::vector这样的序列容器和其他容器没有这种类型的额外重载。
因此,如果你添加const_iterator重载并删除iterator重载,并且iteratorconst_iterator不是同一类型,那么重载解析就有可能变得不明确,而在C
11之前不是这样。例如,如果键类型具有来自iterator的构造函数。
因此,LWG issue 2059的解决方案将旧的iterator重载作为缺陷报告添加回去。对于C++11添加的无序关联容器,它们可能是以相同的方式添加的,这样两种容器之间就不会有不必要的接口差异。

相关问题