Понимание разницы между std::erase и std::remove
Алгоритм std::remove — это универсальный инструмент, предназначенный для работы для любой пары прямых итераторов, что делает его применимым к широкому спектру контейнеров и сценариев. В отличие от своего аналога std::erase, который эффективно удаляет элементы из контейнера, std::remove только переупорядочивает элементы.
1. Раскрытие нюансов std::remove
std::remove работает путем логического разделения контейнера на два раздела: раздел, содержащий элементы, которые нужно удалить, и раздел, содержащий оставшиеся элементы. Это достигается путем перебора контейнера и перемещения неудаленных элементов вперед, эффективно перезаписывая удаленные элементы. Однако важно отметить, что std::remove на самом деле не удаляет удаленные элементы; они остаются в памяти, но фактически скрыты от просмотра.
Такое поведение становится очевидным при использовании std::remove в сочетании с функцией size() контейнера. После удаления элемента с помощью std::remove функция std::size() продолжит возвращать исходный размер контейнера, даже если некоторые элементы логически удалены. Размер контейнера меняется только после использования std::erase для физического удаления скрытых элементов.
2. Визуализация влияния std::remove
Рассмотрим фрагмент кода, представленный в исходном вопросе:
std::vector a;
a.push_back(1);
a.push_back(2);
std::remove(a.begin(), a.end(), 1);
int s = a.size();
После выполнения std::remove вектор по-прежнему содержит два элемента (2 и 2), но первый элемент (1) логически удаляется и скрывается из поля зрения. Таким образом, std::size() возвращает 2, несмотря на наличие скрытого удаленного элемента.
3. Использование std::erase для физического удаления
Чтобы физически удалить удаленные элементы и обновить размер контейнера, в игру вступает std::erase. Вызывая std::erase с парой итераторов, возвращаемой std::remove в качестве первого аргумента, вы можете удалить скрытые удаленные элементы и уменьшить размер контейнера:
a.erase(std::remove(a.begin(), a.end(), 1), a.end());
В этом случае std::erase физически удаляет элемент 1, оставляя вектор с одним элементом (2) и обновленный размер 1.
4. Понимание области действия утилиты std::remove
Хотя std::remove не предназначен исключительно для использования в сочетании с std::erase, он находит широкое применение в различных сценариях, где требуется логическое разделение элементы необходимы. Например, вы можете использовать std::remove, чтобы:
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3