Подтвердить что ты не робот

В С++ 17, почему ассоциативные контейнеры имеют функцию члена erase, которая принимает (не-`` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `` `

См., например, http://en.cppreference.com/w/cpp/container/map/erase

В С++ 03 было три перегрузки:

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

В С++ 11 первая и вторая перегрузки были изменены, чтобы принять const_iterator, чтобы их можно было вызвать с помощью iterator или const_iterator. Первая перегрузка была также улучшена за счет возврата итератора к элементу после того, как он был удален:

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

В С++ 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, ни для любого из контейнеров последовательности, таких как vector, deque и list.

4b9b3361

Ответ 1

Это было сделано для устранения дефекта 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) устраняет эту проблему.