Iterowanie przez kontenery STL i usuwanie / dodawanie wielu elementów
Jednym z najczęstszych błędów występujących w moim kodzie jest modyfikowanie kontenerów STL podczas pętli.
Elementy są usuwane lub dodawane podczas wykonywania pętli, więc zazwyczaj spotykam się z wyjątkami poza granicami.
Moje pętle zazwyczaj wyglądają tak:
for (auto& Item : Items) { // Will not work when Items container is modified
//... loop logic
}
Gdy można usunąć wiele elementów, używam tego potworności:
for (int Index=Items.size()-1;Index<=0;Index--) {
if (Index<Items.size()) { //Because multiple items can be removed in a single loop
//... loop logic
}
}
To wygląda źle i sprawia, że czuję się źle, używając tej drugiej opcji. Powodem usunięcia wielu elementów są zdarzenia, w których pojedyncze zdarzenie może usunąć dowolną liczbę elementów.
Oto pseudo kod ilustrujący, kiedy to nastąpi:
// for each button in vector<button> {
// process button events
// event adds more buttons to vector<button>
// *ERROR* vector<button> is modified during loop.
// }
W innym przykładzie wyobraź sobie wektor z następującymi elementami:
// 0 1 2 3 4 5 6 7 8 9
Zaczynamy naszą pętlę od0
i przejdź element po elemencie. W4
, Chcę usunąć elementy1
,4
i9
więc nie możemy tutaj użyć normalnej pętli.