Historique de la question :
Apparus dans la STL en C++98, les itérateurs ont permis de s'abstraire des structures de données spécifiques, offrant un accès unifié aux éléments du conteneur. Avec l'adoption de C++20, les ranges standard ont été ajoutées, ce qui a encore amélioré l'expressivité et la sécurité lors du travail avec des conteneurs.
Problème :
Une mauvaise manipulation des itérateurs peut entraîner des erreurs d'exécution : dépassement des limites du conteneur, invalidation après modifications. Le support de différents types d'itérateurs peut conduire à un comportement inattendu si on les confond. Le travail "manuel" avec begin()/end() nécessite de la discipline.
Solution :
Utiliser le type d'itérateur correspondant aux capacités du conteneur (par exemple, l'accès aléatoire n'est possible qu'avec vector/deque/array). Ne pas conserver d'itérateurs invalidés. Pour les tâches modernes, privilégier les ranges et algorithmes standardisés.
Exemple de code :
#include <vector> #include <algorithm> #include <iostream> #include <ranges> int main() { std::vector<int> vec{1, 2, 3, 4, 5}; // Itération via itérateur for (auto it = vec.begin(); it != vec.end(); ++it) { std::cout << *it << " "; } // Itération via range for (int x : vec | std::ranges::views::filter([](int v){return v % 2 == 0;})) { std::cout << x << " "; } return 0; }
Caractéristiques clés :
Que se passe-t-il avec l'itérateur std::vector après l'appel à push_back ?
Si après push_back la capacité du conteneur augmente (réajustement), tous les anciens itérateurs et références deviennent invalides. Après push_back sans changement de capacité, les itérateurs sont conservés. Il est plus sûr de ne pas garder d'itérateurs entre les modifications.
Quelle est la différence entre un itérateur random-access et un itérateur bidirectional ?
Le random-access supporte l'arithmétique (it + n) et l'accès par index (it[n]), tandis que le bidirectional ne supporte que ++ et --. Tous les conteneurs STL ne supportent pas le random-access.
Les algorithmes standards de la STL peuvent-ils travailler avec des pointeurs normaux ?
Oui, car un pointeur en C++ satisfait entièrement aux exigences d'un itérateur random-access.
Dans une boucle sur std::list, le développeur modifie directement le conteneur avec la méthode erase, sans mettre à jour l'itérateur, ce qui entraîne une erreur d'exécution.
Avantages :
Inconvénients :
Avant de modifier le conteneur, l'itérateur suivant est toujours conservé. On utilise les algorithmes standards erase-remove idiom pour les vecteurs ou list::remove_if pour les listes.
Avantages :
Inconvénients :