Удаление элемента из вектора при повторении?

У меня есть вектор, который содержит элементы, которые являются активными или неактивными. Я хочу, чтобы размер этого вектора оставался небольшим для проблем с производительностью, поэтому я хочу, чтобы элементы, отмеченные как неактивные, были удалены из вектора. Я попытался сделать это во время итерации, но я получаю ошибку «векторные iteratorы несовместимы».

vector::iterator i = orbsList.begin(); while(i != orbsList.end()) { bool isActive = (*i).active; if(!isActive) { orbsList.erase(i++); } else { // do something with *i ++i; } } 

Наиболее читаемым способом, который я делал в прошлом, является использование std::vector::erase std::remove_if сочетании с std::remove_if . В приведенном ниже примере я использую эту комбинацию, чтобы удалить любое число меньше 10 из вектора.

( Для non-c ++ 0x вы можете просто заменить lambda ниже своим собственным предикатом:)

 // a list of ints int myInts[] = {1, 7, 8, 4, 5, 10, 15, 22, 50. 29}; std::vector v(myInts, myInts + sizeof(myInts) / sizeof(int)); // get rid of anything < 10 v.erase(std::remove_if(v.begin(), v.end(), [](int i) { return i < 10; }), v.end()); 

Я согласен с ответом Вилкса. Вот реализация:

 // curFiles is: vector < string > curFiles; vector< string >::iterator it = curFiles.begin(); while(it != curFiles.end()) { if(aConditionIsMet) { it = curFiles.erase(it); } else ++it; } 

Вы можете это сделать, но вам придется перетасовать ваше while() , я думаю. Функция erase() возвращает iterator в следующий элемент после iterator erase(iterator position); : iterator erase(iterator position); , Цитата из стандарта от 23.1.1 / 7:

Итератор возвращается из a.erase (q) указывает на элемент, следующий за q до стирания элемента. Если такой элемент не существует, возвращается a.end ().

Хотя, возможно, вы должны использовать идиому Erase-remove .

Если кому-то нужна работа над индексами

 vector vector; for(int i=0;i<10;++i)vector.push_back(i); int size = vector.size(); for (int i = 0; i < size; ++i) { assert(i > -1 && i < (int)vector.size()); if(vector[i] % 3 == 0) { printf("Removing %d, %d\n",vector[i],i); vector.erase(vector.begin() + i); } if (size != (int)vector.size()) { --i; size = vector.size(); printf("Go back %d\n",size); } } 

Возможно, вам захочется использовать std::list вместо std::vector для вашей структуры данных. Он более безопасен (менее подвержен ошибкам) ​​для использования при объединении стирания с итерацией.

По их словам, iteratorы вектора становятся недействительными на vector::erase() независимо от того, какую форму увеличения iteratorа вы используете. Вместо этого используйте целочисленный индекс.

Удаление элементов из середины вектора приведет к аннулированию всех iteratorов к этому вектору, поэтому вы не сможете этого сделать ( обновите : не прибегая к предложению Вилкса).

Кроме того, если вы беспокоитесь о производительности, стирание предметов из середины вектора – это плохая идея. Возможно, вы хотите использовать std::list ?

  • Краткое описание запрограммированных правил свертывания ссылок: (1) A & & -> A &, (2) A & && -> A &, (3) A && & -> A & и (4) A && && -> A &&
  • Является std :: vector или boost :: vector thread safe?
  • Как удалить элементы из контейнеров STL?
  • C ++ сортировка и отслеживание индексов
  • Нечувствительность к регистру std :: string.find ()
  • Сортировка вектора пользовательских объектов
  • Почему я не могу создать вектор ссылок?
  • Приращение iteratorов: ++ это более эффективно, чем это ++?
  • Получение вектора в функцию, которая ожидает вектор
  • Что происходит с тем, что происходит с памятью с памятью std :: deque?
  • Есть ли способ доступа к базовому контейнеру контейнеров-контейнеров STL?
  • Давайте будем гением компьютера.