Un itérateur est une abstraction d'un pointeur. Il est utilisé pour parcourir les éléments d'un conteneur, un processus appelé itération. Contrairement à un pointeur brut, un itérateur est une classe disposant d'opérations prédéfinies et contrôlées.
Un itérateur est une classe possédant un pointeur comme donnée membre et des opérateurs prédéfinis. Il permet de contrôler les opérations autorisées : on peut définir un itérateur qui avance seulement (++ sans --), ou qui lit sans écrire, ou inversement.
Un itérateur peut masquer la structure interne du conteneur. L'utilisateur crée un objet de type itérateur et accède aux éléments sans connaître les détails d'implémentation.

Types d'itérateurs
Les itérateurs sont classés en cinq catégories, selon les opérations qu'ils supportent :

Itérateur d'entrée
Un itérateur d'entrée peut utiliser l'opérateur de déréférencement uniquement pour lire depuis un conteneur. Il traite le conteneur comme une source de données.
Itérateur de sortie
Un itérateur de sortie peut utiliser l'opérateur de déréférencement uniquement pour écrire dans un conteneur. La lecture n'est pas autorisée.
Itérateur avant
Un itérateur avant peut lire et écrire. Il combine les capacités des itérateurs d'entrée et de sortie, mais ne se déplace qu'en avant.
Itérateur bidirectionnel
Un itérateur bidirectionnel peut se déplacer dans les deux sens. Les opérateurs ++ et -- sont tous les deux définis.
Itérateur à accès aléatoire
L'itérateur le plus puissant. Il supporte en plus les opérateurs +, - et les quatre opérateurs relationnels (<, <=, >, >=), ce qui permet l'utilisation de l'opérateur d'index [].
| Itérateur | Mouvement | Lecture | Écriture | * | ++ | -- | == et != | <, <=, >, >= | + et - |
|---|---|---|---|---|---|---|---|---|---|
| Entrée | En avant | ||||||||
| Sortie | En avant | ||||||||
| Avant | En avant | ||||||||
| Bidirectionnel | Avant et arrière | ||||||||
| Accès aléatoire | Avant et arrière |
Un conteneur définit normalement deux catégories d'itérateurs : régulier (iterator) et inverse (reverse_iterator). Dans un itérateur régulier, ++ avance vers la fin ; dans un inverse, ++ avance vers le début.

Fournisseurs d'itérateurs
| Itérateur | Fournisseur (classe) |
|---|---|
| Itérateur d'entrée | istream |
| Itérateur de sortie | ostream |
| Itérateur avant | — |
| Itérateur bidirectionnel | list, set, multiset, map, multimap |
| Itérateur à accès aléatoire | vector, deque, array |
Opérations sur les itérateurs
Les classes conteneurs fournissent plusieurs opérations pour manipuler les itérateurs, définies dans l'en-tête <iterator>.
begin / end
begin() renvoie un itérateur pointant sur le premier élément. end() renvoie un itérateur pointant sur l'élément après le dernier (sentinelle de fin de parcours).
Exemple n°1 — Parcours avec begin() et end()
#include <iostream>
#include <string>
#include <iterator>
#include <vector>
using namespace std;
int main() {
vector<string> jrs = {"Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"};
cout << "Le premier element est : " << *std::begin(jrs) << '\n';
vector<string>::iterator it;
cout << "Les jours par begin() et end() :" << endl;
for (it = std::begin(jrs); it < std::end(jrs); it++)
cout << *it << " \t";
return 0;
}Le premier element est : Lundi Les jours par begin() et end() : Lundi Mardi Mercredi Jeudi Vendredi Samedi Dimanche
advance
advance(it, n) déplace l'itérateur it de n positions. Pour un itérateur à accès aléatoire, il utilise l'opérateur + en une seule opération ; sinon il applique ++ répétitivement.
Exemple n°2 — advance
vector<string> jrs = {"Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"};
vector<string>::iterator it = std::begin(jrs);
std::advance(it, 3);
cout << "La position apres avoir avance de 3 : " << *it;La position apres avoir avance de 3 : Jeudi
next / prev
next(it, n) renvoie un itérateur pointant n positions en avant, sans modifier it. prev(it, n) renvoie un itérateur n positions en arrière.
Exemple n°3 — Parcours avec next() et prev()
vector<string>::iterator it = std::begin(jrs);
while (it < std::end(jrs)) {
cout << *it << '\t';
it = std::next(it);
}
cout << '\n';
cout << "ordre inverse :" << endl;
it = std::prev(std::end(jrs), 1);
while (it > std::begin(jrs)) {
cout << *it << '\t';
it = std::prev(it);
}Lundi Mardi Mercredi Jeudi Vendredi Samedi Dimanche ordre inverse : Dimanche Samedi Vendredi Jeudi Mercredi Mardi
Exemple n°4 — Accès au 4ème et avant-dernier éléments
it = std::begin(jrs);
cout << "4eme element : " << *std::next(it, 3) << '\n';
it = std::end(jrs);
cout << "Avant dernier element : " << *std::prev(it, 2);4eme element : Jeudi Avant dernier element : Samedi
distance
distance(debut, fin) renvoie le nombre d'éléments entre deux itérateurs.
Exemple n°5 — distance
vector<string>::iterator debut = jrs.begin();
vector<string>::iterator fin = jrs.end();
cout << "Distance entre begin et end : " << std::distance(debut, fin);Distance entre begin et end : 7
Itérateur à accès aléatoire
Pour un itérateur à accès aléatoire (fourni par vector, deque...), les opérateurs + et - permettent un déplacement direct sans boucle.
Exemple n°6 — Déplacement par arithmétique directe
vector<string>::iterator it = jrs.begin();
cout << "deplacement de 3 pas : " << *(it + 3) << '\n';
it = jrs.end();
cout << "3 pas depuis la fin : " << *(it - 3);deplacement de 3 pas : Jeudi 3 pas depuis la fin : Vendredi
begin() et end() délimitent le conteneur. advance() modifie l'itérateur en place. next() et prev() renvoient un nouvel itérateur sans modifier l'original. distance() calcule l'écart entre deux itérateurs.
Discussion (0)
Soyez le premier à laisser un commentaire !
Laisser un commentaire
Votre commentaire sera visible après modération.