На самом деле std::remove
не удаляет элемент из контейнера.Цитируется здесь
Удалить удаляет из диапазона [first, last)
все элементы, равные value
.То есть, remove возвращает итератор new_last
такой, что диапазон [first, new_last)
не содержит элементов, равных value
. Итераторы в диапазоне [new_last, last)
все все еще разыменовываются , но элементы, на которые они указывают, являются неопределенными . Удалить является стабильным, означая, что относительный порядокэлементов, которые не равны значению, не изменяется.
То есть std::remove
работает только с парой итераторов и ничего не знает о контейнере, который фактически содержит элементы.На самом деле, std::remove
не может знать нижележащий контейнер, потому что он никак не может от пары итераторов узнать о контейнере, к которому принадлежат итераторы.Так что std::remove
на самом деле не удаляет элементы, просто потому, что не может .Единственный способ * на самом деле удалить элемент из контейнера - вызвать функцию-член для этого контейнера.
Поэтому, если вы хотите удалить элементы, используйте Erase-RemoveИдиома :
v.erase(std::remove(v.begin(), v.end(), 10), v.end());
Идиома erase-remove настолько распространена и полезна, что std::list
добавила еще одну функцию-член под названием list::remove
, которая производиттот же эффект, что и для идиомы erase-remove
.
std::list<int> l;
//...
l.remove(10); //it "actually" removes all elements with value 10!
Это означает, что вам не нужно использовать идиому erase-remove
при работе с std::list
.Вы можете напрямую вызвать функцию-член list::remove
.