Geschiedenis van de kwestie:
Kenmerkend voor de STL in C++98, maakten iterators het mogelijk om abstractie te creëren van specifieke datastructuren, waardoor een uniforme toegang tot de elementen van een container werd gewaarborgd. Met de aanname van C++20 is de standaard ranges toegevoegd, wat de expressiviteit en veiligheid bij het werken met containers verder verhoogde.
Probleem:
Incorrecte omgang met iterators kan leiden tot runtimefouten: toegang buiten de grenzen van de container, invalidatie na wijzigingen. De ondersteuning van verschillende soorten iterators kan leiden tot onverwacht gedrag als ze door elkaar worden gehaald. Handmatig werken met begin()/end() vereist discipline.
Oplossing:
Gebruik het type iterator dat resoneert met de mogelijkheden van de container (bijvoorbeeld random access alleen bij vector/deque/array). Sla geen ongevalideerde iterators op. Voor moderne taken moet men vaker gebruikmaken van gestandaardiseerde ranges en algoritmen.
Codevoorbeeld:
#include <vector> #include <algorithm> #include <iostream> #include <ranges> int main() { std::vector<int> vec{1, 2, 3, 4, 5}; // Iteratie via iterator for (auto it = vec.begin(); it != vec.end(); ++it) { std::cout << *it << " "; } // Iteratie via range for (int x : vec | std::ranges::views::filter([](int v){return v % 2 == 0;})) { std::cout << x << " "; } return 0; }
Belangrijke kenmerken:
Wat gebeurt er met de std::vector iterator na het aanroepen van push_back?
Als na push_back de capaciteit van de container vergroot wordt (herstructurering), worden alle oude iterators en referenties ongeldig. Na push_back zonder wijziging van de capaciteit blijven de iterators behouden. Het is betrouwbaarder om geen iterators op te slaan tussen wijzigingen.
Wat is het verschil tussen een random-access iterator en een bidirectional iterator?
Random-access ondersteunt wiskunde (it + n) en toegang op index (it[n]), terwijl bidirectional alleen ++ en -- ondersteunt. Niet alle STL-containers ondersteunen random-access.
Kunnen standaard STL-algoritmen werken met gewone pointers?
Ja, omdat een pointer in C++ volledig voldoet aan de eisen van een random-access iterator.
In een loop door std::list wijzigt de ontwikkelaar de container direct met de methode erase, zonder de iterator bij te werken, wat leidt tot een runtime-fout.
Voordelen:
Nadelen:
Vóór het aanpassen van de container wordt altijd de volgende iterator opgeslagen. Standaardalgoritmen zoals erase-remove idiom voor vectors of list::remove_if voor lijsten worden gebruikt.
Voordelen:
Nadelen: