Partager via


Iterators

Un itérateur est un objet qui peut itérer sur les éléments dans un conteneur de bibliothèque standard C++ et fournir un accès à des éléments spécifiques. Les conteneurs de bibliothèque standard C++ fournissent tous des itérateurs permettant aux algorithmes d’accéder à leurs éléments de façon standard, sans avoir à se préoccuper du type de conteneur où les éléments sont stockés.

Vous pouvez utiliser des itérateurs explicitement à l’aide de fonctions membres et globales telles que et des opérateurs tels que begin() ++ et end() -- pour avancer ou reculer. Vous pouvez également utiliser des itérateurs implicitement avec une boucle range-for ou (pour certains types d’itérateurs) l’opérateur []d’indice .

Dans la bibliothèque standard C++, le début d’une séquence ou d’une plage est le premier élément. La fin d'une séquence ou d'une plage est toujours définie comme étant à l'emplacement suivant le dernier élément. Les fonctions begin globales et end retournent des itérateurs dans un conteneur spécifié. La boucle d'itérateur explicite standard sur tous les éléments d'un conteneur ressemble à ceci :

vector<int> vec{ 0,1,2,3,4 };
for (auto it = begin(vec); it != end(vec); it++)
{
    // Access element using dereference operator
    cout << *it << " ";
}

La même chose peut être accomplie plus simplement avec une boucle for basée sur un intervalle :

for (auto num : vec)
{
    // no dereference operator
    cout << num << " ";
}

Il existe cinq catégories d'itérateurs. Par ordre de puissance croissante, les catégories sont :

  • Sortie. Un itérateur X de sortie peut itérer le transfert sur une séquence à l’aide de l’opérateur ++ et peut écrire un élément une seule fois, à l’aide de l’opérateur * .

  • Entrée. Un itérateur X d’entrée peut effectuer une itération sur une séquence à l’aide de l’opérateur ++ et lire un élément n’importe quel nombre de fois à l’aide de l’opérateur*. Vous pouvez comparer les itérateurs d’entrée à l’aide des opérateurs et != des == opérateurs. Une fois que vous incrémentez une copie d’un itérateur d’entrée, aucune des autres copies ne peut être comparée, déconseillée ou incrémentée par la suite.

  • Transférer. Un itérateur X de transfert peut itérer vers l’avant sur une séquence à l’aide de l’opérateur ++ et peut lire n’importe quel élément ou écrire des éléments non const n’importe quel nombre de fois à l’aide de l’opérateur * . Vous pouvez accéder aux membres d’élément à l’aide de l’opérateur -> et comparer les itérateurs avant à l’aide des opérateurs et != des == opérateurs. Vous pouvez effectuer plusieurs copies d'un itérateur vers l'avant, chacune d'elles pouvant être déréférencée et incrémentée indépendamment. Un itérateur de transfert initialisé sans référence à un conteneur est appelé itérateur de transfert Null. La comparaison d'itérateurs vers l'avant null donne toujours une égalité.

  • Bidirectionnel. Un itérateur X bidirectionnel peut prendre la place d’un itérateur avant. Toutefois, vous pouvez également décrémenter un itérateur bidirectionnel, comme dans --X, X--ou (V = *X--). Vous pouvez accéder aux membres de l'élément et comparer des itérateurs bidirectionnels de la même façon que pour des itérateurs vers l'avant.

  • Accès aléatoire. Un itérateur X à accès aléatoire peut prendre la place d’un itérateur bidirectionnel. Avec un itérateur d’accès aléatoire, vous pouvez utiliser l’opérateur [] d’indice pour accéder aux éléments. Vous pouvez utiliser les opérateurs et += --= les +opérateurs pour avancer ou reculer un nombre spécifié d’éléments et calculer la distance entre les itérateurs. Vous pouvez comparer des itérateurs bidirectionnels à l’aide ==de , , !=, <, >, , <=et >=.

Tous les itérateurs peuvent être affectés ou copiés. Elles sont supposées être des objets légers et sont souvent passées et retournées par valeur, et non par référence. Notez également qu'aucune des opérations décrites précédemment ne peut lever une exception lorsqu'elle est effectuée sur un itérateur valide.

La hiérarchie des catégories d'itérateur peut être résumée en indiquant trois séquences. Pour l'accès en écriture seule à une séquence, vous pouvez utiliser l'une des catégories suivantes :

itérateur de sortie
-> itérateur avant
-> itérateur bidirectionnel
-> itérateur d’accès aléatoire

La flèche droite signifie « peut être remplacée par ». Tout algorithme qui appelle un itérateur de sortie doit fonctionner correctement avec un itérateur de transfert, par exemple, mais pas de l’autre façon.

Pour l'accès en lecture seule à une séquence, vous pouvez utiliser l'une des catégories suivantes :

itérateur d’entrée
-> itérateur avant
-> itérateur bidirectionnel
-> itérateur d’accès aléatoire

Un itérateur d'entrée est le plus faible de toutes les catégories, dans ce cas.

Enfin, pour l'accès en lecture/écriture à une séquence, vous pouvez utiliser l'une des catégories suivantes :

itérateur avant
-> itérateur bidirectionnel
-> itérateur d’accès aléatoire

Un pointeur d'objet peut toujours servir d'itérateur à accès aléatoire, il peut donc être utilisé comme catégorie d'itérateur s'il prend en charge l'accès approprié en lecture et en écriture à la séquence qu'il désigne.

Un itérateur Iterator autre qu'un pointeur d'objet doit également définir les types de membres requis par la spécialisation iterator_traits<Iterator>. Ces exigences peuvent être satisfaites en dérivant Iterator de l’itérateur de classe de base publique.

Il est important de comprendre les promesses et limitations de chaque catégorie d’itérateur pour voir comment les itérateurs sont utilisés par des conteneurs et des algorithmes dans la bibliothèque C++ Standard.

Remarque

Vous pouvez éviter d'utiliser des itérateurs explicitement avec des boucles for basées sur un intervalle. Pour plus d’informations, consultez l’instruction basée sur la plage.

Microsoft C++ propose désormais des itérateurs vérifiés et des itérateurs de débogage pour vous assurer que vous ne remplacez pas les limites de votre conteneur. Pour plus d’informations, consultez itérateurs vérifiés et Itérateurs de débogage, prise en charge.

Voir aussi

Informations de référence sur la bibliothèque standard C++
Sécurité des threads dans la bibliothèque C++ Standard