12

たとえば、 http://en.cppreference.com/w/cpp/container/map/eraseを参照してください。

C++03 には、次の 3 つのオーバーロードがありました。

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

C++11 では、1 番目と 2 番目のオーバーロードが take に変更され、または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 では、const 以外のオーバーロードが再導入されました。

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

なぜこれが必要なのですか?ranged erase、 、、、insertなどのシーケンス コンテナのいずれにも追加されませんでした。vectordequelist

4

1 に答える 1

15

これは、LWG 欠陥 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)この問題が修正されます。

于 2016-12-21T07:11:47.147 に答える