C11将std::vector::erase
改为const_iterator
,而不是iterator
。同样的事情也适用于std::deque
和std::list
,而std::forward_list
在C11中带有erase_after
,它也需要const_iterator
。
相比之下,std::set::erase
保留了它的iterator
重载,C11只是添加了const_iterator
重载。这同样适用于所有关联容器:std::map
、std::multiset
和std::multimap
都保留了C11之前的iterator
重载,而std::unordered_set
、std::unordered_map
、std::unordered_multiset
和std::unordered_multimap
都是通过iterator
和const_iterator
重载引入的。
事实上,对于所有四个集合类,iterator
and const_iterator
may very well be the same type。
为什么会有差异?除了与非关联容器的不一致之外,范围擦除重载也存在不一致,它们都在C++11中被更改为采用一对const_iterator
s而不是一对iterator
s。由于iterator
必须可转换为const_iterator
,因此无需为范围擦除设置所有四种可能的参数组合。类似地,对于单值擦除,不需要“所有两个组合”,那么为什么要保持iterator
过载呢?
1条答案
按热度按时间hfwmuf9z1#
最初在C11中,旧的
iterator
重载被所有这些容器的const_iterator
重载所取代。然而,关联容器总是有额外的
erase
重载,它们将键类型作为参数。像std::vector
这样的序列容器和其他容器没有这种类型的额外重载。因此,如果你添加
const_iterator
重载并删除iterator
重载,并且iterator
和const_iterator
不是同一类型,那么重载解析就有可能变得不明确,而在C11之前不是这样。例如,如果键类型具有来自iterator
的构造函数。因此,LWG issue 2059的解决方案将旧的
iterator
重载作为缺陷报告添加回去。对于C++11添加的无序关联容器,它们可能是以相同的方式添加的,这样两种容器之间就不会有不必要的接口差异。