Подскажите, как корректно пройтись по вектору и удалить некоторые его элементы.
Т.е., корректно ли выполнять такие действия?
for (auto it = arr.begin(); it != arr.end(); it++)
{
if (check(*it) == false)
arr.erase(it);
}
Или возникнут проблемы с итератором после удаления первого элемента?
Прочитал комментарии, всем спасибо за помощь
Пересмотрел код и понял, что не совсем полно поставил задачу:
for (auto it = arr.begin(); it != arr.end(); it++)
{
if (check(*it) == false)
{
// сделать-что-то полезное с данными, которые потом будут удалены
arr.erase(it);
}
}
Если воспользоваться советом @Harry, то тогда код можно же преобразовать к такому:
arr.erase(remove_if(arr.begin(), arr.end(), [](auto x) {
if (check(x))
{
// сделать что-то полезное с данными из x
return true;
}
return false;
}), arr.end());
?
А почему не так:
arr.erase(remove_if(arr.begin(),arr.end(),
[](auto x){ return !check(x); }),
arr.end());
? Как по мне - понятнее и никаких проблем с итераторами... Вероятно, еще и быстрее, чем убирать по одному элементу...
Если перепишете check
так, чтоб работал наоборот - то и лямбда-выражение (или bind
) не потребуется.
Если уж позарез нужен цикл - то воспользуйтесь тем, что erase
возвращает итератор на элемент, следующий за удаленным:
for(auto i = arr.begin(); i != arr.end();
i = (check(*i) == false) ? arr.erase(i) : i+1);
Но учтите, что тут сложность - квадратичная, в отличие от remove_if
(спасибо @pavel).
erase
вернёт следующий итератор, элемент будет удалён, но будет проблема с инкрементом, так что нужно добавить вспомогательный код.
for (auto it = arr.begin(); it != arr.end(); it++)
{
if (check(*it) == false){
it = arr.erase(it);
--it;
}
}
Итератор после удаления станет не валидным и it++ сделать будет нельзя. К тому же, на каждую итерацию будет перестроение вектора, что в общем случаем считается тяжелой операцией. Можно перенести все правильные значения в новый вектор:
decltype(arr) new_vector;
new_vector.reserve(arr.size());
for (auto i = 0; i < arr.size(); ++i)
{
new_vector.emplace_back(std::move(arrr[i]));
}
arr.swap(new_vector)
Альтернатива ответу @Komodosh.
Чтобы не декрементировать итератор лишний раз, можно сделать так:
auto it = arr.begin();
while (it != arr.end())
{
if (check(*it) == false)
it = arr.erase(it);
else
it++;
}
Но лучше послушать Harry и взять erase-remove idiom.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Смотрел видео Mike Acton и там рассказывалось, что в геймдеве не используют исключения, RTTI и тд
создал бота, начал использовать telegram api проект собирается при помощи maven докинул зависимость
входящие данные Числа типа double 20 000 000 общая сумма