Выбор ответа Middle Алгоритмы STL и ranges спрашивают часто обновлено

Почему remove не уменьшает vector

Вопрос

После std::remove(v.begin(), v.end(), 0) размер v не изменился. Почему?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Алгоритм не может менять размер: он вернул новый конец, нужен erase. Алгоритм получает пару итераторов и ничего не знает о контейнере, поэтому вызвать у него erase не может.

Варианты ответа

  1. Алгоритм не может менять размер: он вернул новый конец, нужен eraseправильный ответ
  2. Это известный баг стандартной библиотеки, исправленный в C++20
  3. Потому что нулей не было: при найденных нулях размер уменьшается
  4. std::remove меняет размер только у std::list, а у вектора нет

Разбор

Алгоритм получает пару итераторов и ничего не знает о контейнере, поэтому вызвать у него erase не может. Отсюда идиома v.erase(std::remove(...), v.end()) и функции C++20 std::erase и std::erase_if, которые делают оба шага.

  • Поведение задокументировано и намеренно.
  • Размер не меняется независимо от того, были ли нули.
  • У std::list есть свой метод remove, который удаляет узлы, но алгоритм std::remove размер не меняет и для списка.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.