在C ++ 17中,为什么关联容器有一个`erase`成员函数,它接受(非`constst`)`iterator`?

时间:2016-12-21 06:47:14

标签: c++ iterator stdmap c++17 const-iterator

参见,例如, http://en.cppreference.com/w/cpp/container/map/erase

在C ++ 03中有三个重载:

void erase( iterator pos );
void erase( iterator first, iterator last );
size_type erase( const key_type& key );

在C ++ 11中,第一次和第二次重载已更改为const_iterator,因此可以使用iteratorconst_iterator调用它们。第一次重载也通过在删除之后将迭代器返回到元素来改进:

iterator erase( const_iterator pos );
void erase( const_iterator first, const_iterator last );
size_type erase( const key_type& key );

在C ++ 17中,重新引入了非常量重载:

iterator erase( const_iterator pos );
iterator erase( iterator pos );
void erase( const_iterator first, const_iterator last );
size_type erase( const key_type& key );

为什么需要这个?它不是为范围erase添加,也不是为insert添加,也不是为vectordequelist等任何序列容器添加的。< / p>

1 个答案:

答案 0 :(得分:15)

这样做是为了解决LWG defect 2059问题。考虑链接中的示例

#include <map>

struct X
{
  template<typename T>
  X(T&) {}
};

bool operator<(const X&, const X&) { return false; }

void erasor(std::map<X,int>& s, X x)
{
  std::map<X,int>::iterator it = s.find(x);
  if (it != s.end())
    s.erase(it);
}

最后对map::erase的调用不明确,因为map::erase(const_iterator)map::erase(key_type const&)都是同样出色的匹配,因为它们都需要用户定义的转化。

重新引入map::erase(iterator)重载可以解决此问题。