Страницы

Поиск по вопросам

среда, 10 июля 2019 г.

Удаление элемента списка при for (auto& i : list)

Есть цикл:
for ( auto& whizbang : m_whizbangs ) { if ( IsClush((*whizbang), (*whizbang).GetDirection(), time) ) { (*whizbang).Hit(); m_whizbangs.remove(whizbang);
} else { (*whizbang).Move(time); } }
Выдаёт ошибку, что итератор не увеличиваемый. У меня была такая ошибка, когда я работал с таким синтаксисом:
for (std::list>::iterator i = m_whizbangs.begin(); i < m_whizbangs.end())
И я её исправил, тогда я удалял так:
if (...) i = m_whizbangs.erase(i); else ++i;
Как нужно удалять при таком синтаксисе? И можно ли как-нибудь использовать erase, а не remove, так как remove по сути ничего не удаляет, а просто заполняет конец списка мусором.


Ответ

Диапазонная версия цикла for обеспечивает доступ к элементу, а не к итератору, т.е. нормальное удаление элементов в таком цикле не является возможным (можно модифицировать элемент в контейнере, но нельзя модифицировать сам контейнер). Чтобы это понимать достаточно взглянуть на то, во что по Стандарту разворачивается range-based-for
The range-based for statement
for ( for-range-declaration : for-range-initializer ) statement is equivalent to
{ auto &&__range = for-range-initializer ; auto __begin = begin-expr ; auto __end = end-expr ; for ( ; __begin != __end; ++__begin ) { for-range-declaration = *__begin; statement } }

Комментариев нет:

Отправить комментарий