En règle générale, les itérateurs sont utilisés pour accéder aux éléments d'un conteneur de manière linéaire; cependant, avec des "itérateurs à accès aléatoire", il est possible d'accéder à n'importe quel élément de la même manière que operator[]
.
Pour accéder à des éléments arbitraires dans un vecteur vec
, vous pouvez utiliser ce qui suit:
vec.begin() // 1st
vec.begin()+1 // 2nd
// ...
vec.begin()+(i-1) // ith
// ...
vec.begin()+(vec.size()-1) // last
Voici un exemple de modèle d'accès typique (versions antérieures de C ++):
int sum = 0;
using Iter = std::vector<int>::const_iterator;
for (Iter it = vec.begin(); it!=vec.end(); ++it) {
sum += *it;
}
L'avantage d'utiliser iterator est que vous pouvez appliquer le même modèle avec d'autres conteneurs :
sum = 0;
for (Iter it = lst.begin(); it!=lst.end(); ++it) {
sum += *it;
}
Pour cette raison, il est vraiment facile de créer un code de modèle qui fonctionnera de la même manière quel que soit le type de conteneur . Un autre avantage des itérateurs est qu'ils ne supposent pas que les données résident en mémoire; par exemple, on pourrait créer un itérateur avant qui peut lire des données à partir d'un flux d'entrée, ou qui génère simplement des données à la volée (par exemple un générateur de plage ou de nombres aléatoires).
Une autre option utilisant std::for_each
et lambdas:
sum = 0;
std::for_each(vec.begin(), vec.end(), [&sum](int i) { sum += i; });
Depuis C ++ 11, vous pouvez utiliser auto
pour éviter de spécifier un nom de type très long et compliqué de l'itérateur comme vu précédemment (ou même plus complexe):
sum = 0;
for (auto it = vec.begin(); it!=vec.end(); ++it) {
sum += *it;
}
Et, en plus, il existe une variante plus simple pour chaque variante:
sum = 0;
for (auto value : vec) {
sum += value;
}
Et enfin, il y a aussi std::accumulate
là où vous devez faire attention si vous ajoutez des nombres entiers ou flottants.