Стирание из std :: vector при выполнении для каждого?

Правильный способ итерации – использовать iteratorы. Однако, я думаю, что, стирая, iterator недействителен.

В основном, что я хочу сделать:

for(iterator it = begin; it != end; ++it) { if(it->somecondition() ) { erase it } } 

Как я могу сделать это без метода v [i]?

благодаря

 struct RemoveTimedEvent { bool operator()(const AguiTimedEvent& pX, AguiWidgetBase* widget) const { return pX.getCaller() == widget; } }; void AguiWidgetContainer::clearTimedEvents( AguiWidgetBase* widget ) { std::vector::iterator it = std::remove_if(timedEvents.begin(), timedEvents.end(), RemoveTimedEvent()); timedEvents.erase(it, timedEvents.end()); } 

erase() возвращает новый iterator:

 for(iterator it = begin; it != end(container) /* !!! */;) { if (it->somecondition()) { it = vec.erase(it); // Returns the new iterator to continue from. } else { ++it; } } 

Обратите внимание, что мы больше не можем сравнивать его с заранее рассчитанным концом, потому что мы можем стереть его и, следовательно, сделать его недействительным. Мы должны каждый раз получать конец.

Лучшим методом может быть объединение std::remove_if и std::remove_if erase() . Вы меняетесь от O (N 2 ) (каждый элемент стирается и сдвигается по мере продвижения) до O (N):

 iterator it = std::remove_if(begin, end, pred); vec.erase(it, vec.end()); 

Где pred – ваш предикат удаления, такой как:

 struct predicate // do choose a better name { bool operator()(const T& pX) const // replace T with your type { return pX.shouldIBeRemoved(); } }; iterator it = std::remove_if(begin, end, predicate()); vec.erase(it, vec.end()); 

В вашем случае вы можете сделать это довольно общим:

 class remove_by_caller { public: remove_by_caller(AguiWidgetBase* pWidget) : mWidget(pWidget) {} // if every thing that has getCaller has a base, use that instead template  // for now a template bool operator()(const T& pX) const { return pX.getCaller() == mWidget; } private: AguiWidgetBase* mWidget; }; std::vector::iterator it = std::remove_if(timedEvents.begin(), timedEvents.end(), remove_by_caller(widget)); timedEvents.erase(it, timedEvents.end()); 

Обратите внимание, что lambda существует для упрощения этого процесса, как в Boost, так и в C ++ 11.

  • Каков наиболее эффективный способ удаления дубликатов и сортировки вектора?
  • Почему я не могу создать вектор lambdas (одного типа) в C ++ 11?
  • Каков наилучший способ конкатенировать два вектора?
  • Инициализация двумерного std :: vector
  • Поиск всех позиций для нескольких элементов в векторе
  • Проверьте, содержит ли вектор данный элемент
  • pop_back () возвращаемое значение?
  • распространение данных внутри вектора
  • Объединение двух std :: векторов
  • std :: вектор и непрерывная память многомерных массивов
  • Как связать вектор
  • Interesting Posts

    bootstrap 3 – как разместить марку в центре навигатора?

    Удаление старого раздела Vista, но это активный системный раздел

    Места, где используются JavaBeans?

    Почему PySpark не может найти py4j.java_gateway?

    Закройте приложение Windows Phone 7

    C ++ int с предшествующим 0 изменяет всю ценность

    Обновить строку с данными из другой строки в одной таблице

    Почему мой подclass не может получить доступ к защищенной переменной своего суперclassа, когда он находится в другом пакете?

    Почему gcc разрешает передавать аргументы в функцию, определенную без аргументов?

    Можно ли смешивать Swift с C ++? Как и файлы Objective – C .mm

    Как реализовать пользовательский атрибут Authorize для следующего случая?

    Использует ли Interlocked.CompareExchange барьер памяти?

    Можно ли использовать переднюю и заднюю камеры одновременно в Android

    Передача общих указателей в качестве аргументов

    JQuery: найдите текст и замените

    Давайте будем гением компьютера.