Un itérateur en C++ est un objet de type pointeur qui pointe vers un élément du conteneur STL. Ils sont généralement utilisés pour parcourir le contenu du conteneur STL en C++. Le principal avantage des itérateurs STL est qu'ils rendent les algorithmes STL indépendants du type de conteneur utilisé. Nous pouvons simplement transmettre l'itérateur aux éléments du conteneur au lieu du conteneur lui-même aux algorithmes STL.
Déclaration de l'itérateur
Chaque conteneur en C++ STL possède son propre itérateur. Nous devons donc déclarer un itérateur comme :
C++
<type>::iterator it;
où
- taper: Type de conteneur pour lequel l'itérateur est déclaré.
- il: Nom attribué à l’objet itérateur.
Nous pouvons ensuite l'initialiser en attribuant un itérateur valide. Si nous avons déjà un itérateur à attribuer au moment de la déclaration, nous pouvons ignorer la déclaration de type en utilisant le auto mot-clé.
C++auto it = iter
où itérer est l'itérateur affecté à l'itérateur it nouvellement créé.
Notre Cours C++ couvre l'utilisation des itérateurs dans la STL en vous assurant de comprendre comment parcourir différents types de conteneurs.
Exemple d'itérateurs
Le programme ci-dessous illustre comment utiliser l'itérateur pour parcourir le conteneur vectoriel :
C++#include using namespace std; int main() { vector<int> v = {1 2 3 4 5}; // Defining an iterator pointing to // the beginning of the vector vector<int>::iterator first = v.begin(); // Defining an iterator pointing // to the end of the vector vector<int>::iterator last = v.end(); // Iterating the whole vector while(first != last) { cout << *first << ' '; first++; } return 0; }
Sortir
1 2 3 4 5
Comme vous l'avez peut-être remarqué, nous avons utilisé vecteur :: début () et vecteur :: fin () fonction. Ces fonctions sont les fonctions membres de std::vector qui renvoient l'itérateur au premier et à un élément après le dernier élément du vecteur. Nous utilisons les itérateurs de retour de ces fonctions pour itérer les vecteurs.
Fonctions de l'itérateur de conteneur
C++ STL fournit certaines fonctions membres dans Conteneur STL qui renvoient les itérateurs au moins au premier et au dernier élément. Ces fonctions membres sont définies dans presque tous les conteneurs STL (en laissant certains conteneurs à accès limité comme empiler file d'attente ) avec le même nom par souci de cohérence.
Le tableau suivant répertorie toutes les méthodes qui renvoient l'itérateur aux conteneurs :
Fonction itérateur | Valeur de retour |
|---|---|
commencer() | Renvoie un itérateur au début du conteneur. |
fin() | Renvoie un itérateur à l'élément théorique juste après le dernier élément du conteneur. |
ccommencer() | Renvoie un itérateur constant au début du conteneur. Un itérateur constant ne peut pas modifier la valeur de l'élément vers lequel il pointe. |
quelques() liste de latex | Renvoie un itérateur constant à l'élément théorique juste après le dernier élément du conteneur. |
rcommencer() | Renvoie un itérateur inverse au début du conteneur. |
rend() | Renvoie un itérateur inverse à l'élément théorique juste après le dernier élément du conteneur. |
crbegin() | Renvoie un itérateur inverse constant au début du conteneur. |
CREND () | Renvoie un itérateur inverse constant à l'élément théorique juste après le dernier élément du conteneur. |
Par exemple si une chose est le nom du vecteur, nous pouvons alors utiliser les méthodes ci-dessus comme indiqué ci-dessous :
C++vec.begin() vec.rbegin() vec.cbegin() vec.crbegin() vec.end() vec.rend() vec.cend() vec.crend()
Opérations des itérateurs
Tout comme l’arithmétique des pointeurs, certaines opérations sont autorisées sur les itérateurs C++. Ils sont utilisés pour fournir différentes fonctionnalités qui augmentent l’importance des itérateurs. Il y en a 5 valides opérations d'itérateur en C++ :
- Déréférencement des itérateurs
- Itérateurs d'incrémentation/décrémentation
- Ajout/soustraction d'entier aux itérateurs
- Soustraire un autre itérateur
- Comparaison des itérateurs
Déréférencement des itérateurs
L'opération de déréférencement permet aux utilisateurs de accès ou mise à jour la valeur de l'élément pointé par l'itérateur. Nous utilisons le (*) opérateur d'indirection pour déréférencer les itérateurs tout comme les pointeurs.
C++// Access *it; // Update *it = new_val;
où nouveau_val est la nouvelle valeur attribuée à l'élément pointé par l'itérateur il .
Itérateurs d'incrémentation/décrémentation
Nous pouvons incrémenter ou décrémenter l'itérateur de 1 en utilisant Opérateurs (++) ou (--) respectivement. L'opération d'incrémentation déplace l'itérateur vers l'élément suivant dans le conteneur tandis que l'opération de décrémentation déplace l'itérateur vers l'élément précédent.
C++it++; // post-increment ++it; // pre-increment it--; // post-decrement --it; // pre-decrement
Ajout/soustraction d'entier aux itérateurs
Nous pouvons également ajouter ou soustraire une valeur entière aux itérateurs. Il s'agira de la position suivante ou précédente de l'itérateur en fonction de la valeur entière ajoutée.
C++// Addition it + int_val; // Subtraction it - int_val;
où int_val sont les valeurs entières qui sont ajoutées ou soustraites à l'itérateur il .
Soustraire un autre itérateur
Nous pouvons soustraire un itérateur d'un autre pour trouver la distance (ou le nombre d'éléments) entre la mémoire vers laquelle ils pointent.
C++it1 - it2
Comparaison des itérateurs
Nous pouvons également tester les deux itérateurs du même type l’un contre l’autre pour trouver la relation entre eux. Nous pouvons utiliser les opérateurs relationnels comme les opérateurs d'égalité (==) et d'inégalité (!=) ainsi que d'autres opérateurs relationnels tels que< > <= >=.
C++it1 != it2 // Equal to it1 == it2 // Not equal to it1 > it2 // Greater than it1 < it2 // Less than it1 >= it2 // Greater than equal to it1 <= it2 // Less than equal to
Types d'itérateurs en C++
Les itérateurs STL peuvent être divisés en fonction des opérations qui peuvent être effectuées sur eux. Il existe 5 principaux types d'itérateurs en C++, répertoriés dans le tableau ci-dessous, ainsi que les conteneurs et les opérations d'itérateur pris en charge.
Itérateur | Description | Conteneurs pris en charge | Opérations prises en charge |
|---|---|---|---|
Itérateur d'entrée | Il s'agit d'un itérateur unidirectionnel utilisé pour lire les valeurs. | Flux d'entrée | Déréférencement de l'égalité des incréments |
Itérateur de sortie | C'est également un itérateur unidirectionnel mais utilisé pour attribuer les valeurs. Il ne peut pas accéder aux valeurs. | Flux de sortie | Déréférencement (écriture uniquement) Incrément |
Itérateurs avant | Il peut accéder et attribuer les valeurs. C'est la combinaison des itérateurs d'entrée et de sortie. | forward_list unordered_map unordered_set | Déréférencement de l'égalité des incréments |
Itérateurs bidirectionnels | Il peut se déplacer dans les deux sens, en avant ou en arrière. Les conteneurs comme list set et multimap prennent en charge les itérateurs bidirectionnels. | liste ensemble de cartes multicarte multiensemble | Déréférencement de l'égalité d'incrémentation/décrémentation |
Itérateurs à accès aléatoire | Les itérateurs à accès aléatoire sont des itérateurs qui peuvent être utilisés pour accéder à des éléments éloignés de l'élément vers lequel ils pointent, offrant les mêmes fonctionnalités que les pointeurs. | chaîne de tableau deque vectorielle livecricket.is | Tous |
Comme nous l'avons peut-être remarqué dans le tableau ci-dessus, en dehors des itérateurs d'entrée et de sortie Au fur et à mesure que nous parcourons le tableau, le type d'itérateur contient les fonctionnalités de l'itérateur ci-dessus ainsi que quelques nouvelles fonctionnalités.
Adaptateurs d'itérateur
Les adaptateurs d’itérateurs en C++ sont un type spécial d’itérateurs construits sur les itérateurs traditionnels pour fournir des fonctionnalités spécialisées. Il existe de nombreux adaptateurs d'itérateurs en C++, dont certains sont indiqués ci-dessous :
Type d'adaptateurs d'itérateur | Description |
|---|---|
Itérateur inverse | L'itérateur inverse est construit sur un type d'opérateur bidirectionnel ou supérieur et permet aux utilisateurs de parcourir le conteneur dans le sens inverse. |
Itérateurs de flux | Les itérateurs de flux, à savoir les itérateurs istream et ostream, sont construits respectivement sur les itérateurs d'entrée et de sortie. Ces itérateurs permettent aux utilisateurs d'utiliser les flux comme conteneurs. |
Déplacer les itérateurs | Les itérateurs de déplacement sont utilisés pour introduire la sémantique de déplacement dans les algorithmes STL. Les itérateurs de déplacement déplacent la propriété des données du conteneur copiées vers le conteneur de copie sans créer de copies supplémentaires. |
Itérateur d'insertion | Les itérateurs d'insertion vous permettent d'insérer les éléments donnés à une certaine position dans le conteneur. Il existe trois itérateurs d'insertion en C++ :
Ces itérateurs peuvent être créés en utilisant back_inserter() front_inserter() insérer() fonctions en C++. |
Fonctions utilitaires d'itérateur en C++
C++ STL fournit les différentes fonctions pour simplifier le travail avec les itérateurs. Ils sont répertoriés dans le tableau ci-dessous :
| Fonction | Description | Syntaxe |
|---|---|---|
| std :: avance | Avance un itérateur d’un nombre spécifique de positions. | avance ( ça n ) |
| std :: suivant | Renvoie l'itérateur qui a un nombre spécifié de positions en avance sur l'itérateur donné. | suivant ( ça n ) |
| Std :: Précédent | Renvoie l'itérateur qui se trouve à un nombre spécifié de positions derrière l'itérateur donné. | précédent ( ça n ) |
| std :: distance | Renvoie le nombre d'éléments entre deux itérateurs. | distance ( il1 il2 ) |
| std :: commencer | Renvoie un itérateur vers le premier élément du conteneur donné. | commencer ( récipient ) |
| std :: fin | Renvoie un itérateur à l'élément suivant le dernier élément du conteneur donné. | fin ( récipient ) |
| std :: rbegin | Renvoie un itérateur inverse vers le dernier élément du conteneur donné. | commencer ( récipient ) |
| std :: rendu | Renvoie un itérateur inverse à l'élément précédant le premier élément du conteneur donné. | rend ( récipient ) |
| std :: inserteur | Crée un itérateur d'insertion qui insère des éléments dans un conteneur à une position spécifiée. | inséreuse ( position du conteneur ) |
| std :: back_inserter | Crée un itérateur d'insertion arrière qui ajoute des éléments à la fin d'un conteneur. | back_inserter ( récipient ) |
| std :: front_inserter | Crée un itérateur d'insertion avant qui insère des éléments à l'avant d'un conteneur. | front_inserter ( récipient ) |
Applications des itérateurs avec exemples
Les itérateurs sont largement utilisés en C++ à de nombreuses fins différentes tout en travaillant avec des conteneurs et des algorithmes STL. Voici quelques applications principales des itérateurs en C++ avec leurs exemples de code :
Traversée des conteneurs
La traversée des conteneurs STL est l'application la plus basique des itérateurs. En cela, nous utilisons les fonctions begin() et end() pour que les itérateurs de début et de fin parcourent l'ensemble du conteneur. Fondamentalement, nous continuons à incrémenter l'itérateur de début jusqu'à ce qu'il ne soit pas égal à la fin.
Exemple
C++#include using namespace std; int main() { set<int> s = {10 20 30 40 50}; // Iterator to the beginning // of the set auto it = s.begin(); // Iterating through the // entire set while (it != s.end()) { // Dereferencing iterator // to access value cout << *it << ' '; // Incrementing the // iterator it++; } return 0; }
Sortir
10 20 30 40 50
Comme le montre le code ci-dessus, nous parcourons le conteneur défini. De même, nous pouvons utiliser la même approche pour parcourir n’importe quel conteneur.
Inverser un conteneur
Les itérateurs inversés vous permettent de parcourir un conteneur de la fin au début sans avoir à gérer manuellement l'inversion.
Exemple
C++#include using namespace std; int main() { vector<int> vec = {10 20 30 40 50}; // Defining reverse iterators // pointing to the reverse // beginning of vec auto it = vec.rbegin(); // Iterating the whole // vector in reverse while (it != vec.rend()) { cout << *it << ' '; it++; } return 0; }
Sortir
50 40 30 20 10
Algorithmes indépendants des conteneurs
Les itérateurs permettent aux algorithmes de fonctionner avec n'importe quel type de conteneur, rendant les fonctions comme std::sort() std::find() et std::for_each() plus flexibles. Vous pouvez transmettre des itérateurs au lieu du conteneur réel.
Exemple
C++#include using namespace std; int main() { vector<int> vec = {30 10 40 10 50}; multiset<int> ms = {10 30 10 20 40 10}; // Using the std::count() algorithm to count // the number of occurences of 10 in vector // and multiset using iterator cout << '10s in Vector: ' << count(vec.begin() vec.end() 10) << endl; cout << '10s in Multiset: ' << count(ms.begin() ms.end() 10); return 0; }
Sortir
10s in Vector: 2 10s in Multiset: 3
Applications supplémentaires des itérateurs
Il existe d'autres applications des itérateurs STL :
- Calcul des distances : L'utilisation des itérateurs std::distance() permet de calculer le nombre d'éléments entre deux positions dans un conteneur.
- Itération de flux : Les itérateurs de flux vous permettent de traiter les flux d'entrée/sortie comme des conteneurs, ce qui facilite la lecture et l'écriture dans les flux à l'aide d'algorithmes STL.
- Déplacer la sémantique dans les algorithmes STL : Les itérateurs de déplacement introduisent la sémantique de déplacement dans les algorithmes STL, ce qui contribue à augmenter les performances et l'efficacité en évitant les copies inutiles. Les données seront déplacées selon les règles de la sémantique de déplacement.
- Itérateurs personnalisés pour les structures de données : Des itérateurs personnalisés peuvent être implémentés pour les structures de données non STL telles que des arbres ou des graphiques afin de fournir la prise en charge des algorithmes STL et de nombreuses autres fonctionnalités. Nous devrons peut-être suivre quelques ensembles de règles et de conventions pour fournir des opérations de décrémentation et d'incrémentation appropriées.