векторные итераторы несовместимы при удалении из вектора

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

std::map<size_t,std::vector<size_t> > myMap;
for (std::map<size_t,std::vector<size_t> >::iterator itMap = myMap.begin();itMap != myMap.end();++itMap )
{
for (std::vector<size_t>::iterator itVec = itMap->second.begin();itVec != itMap->second.end();)
{
auto itNextVec = itVec;
++itNextVec;
if (*itVec == num)
{
itMap->second.erase(itVec );
}
itVec = itNextVec;
}
}

Код вызывает исключение во время выполнения. В VS — vector iterators incompatible,
Может кто-то указать, что является причиной этого?

Спасибо

1

Решение

std::vector::erase возвращает iterator до следующей позиции списка, и поэтому, когда вы делаете стирание, вы должны сделать свой итератор равным возвращаемому значению.

Единственное, что вы должны учитывать, это то, что возвращенный iterator может быть конец, так что вы должны проверить это.

Что лично мне нравится делать, так это после выполнения стирания и получения следующей позиции итератора, я возвращаюсь к предыдущей позиции возвращаемого итератора и затем вызываю продолжение для for loop

Пример:

#include <vector>
#include <iostream>

int main()
{
std::vector<int> myInt;
myInt.push_back(1);myInt.push_back(2);myInt.push_back(3);

for(auto iter = myInt.begin();
iter != myInt.end();
++iter)
{
if(*iter == 1)
{
iter = myInt.erase(iter);
if(iter != myInt.begin())
{
iter = std::prev(iter);
continue;
}
}

std::cout << *iter << std::endl;
}
}

Но стирание внутри цикла итератора не одобряется, потому что оно делает недействительным старый итератор, и это может вызвать много проблем, если вы не планируете их.

6

Другие решения

стирание сделает недействительным итератор

Iterator validity
Iterators, pointers and references pointing to position (or first) and beyond are
invalidated, with all iterators, pointers and references to elements before position (or
first) are guaranteed to keep referring to the same elements they were referring to
before the call.
2

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

Если вы проверите, например, эта ссылка, вы увидите, что erase Функция возвращает итератор для следующего элемента. Продолжайте цикл с этим (не увеличивая его, конечно).

1

Рассмотрите возможность использования другого класса коллекции, чем vector или создание нового вектора с удалением нужных элементов вместо удаления из существующего вектора.

1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector