Зазвичай ітератори використовуються для доступу до елементів контейнера лінійним способом; однак, за допомогою "ітераторів випадкового доступу" можна отримати доступ до будь-якого елемента таким же чином, як і operator[]
.
Для доступу до довільних елементів у векторі vec
, ви можете використовувати наступне:
vec.begin() // 1st
vec.begin()+1 // 2nd
// ...
vec.begin()+(i-1) // ith
// ...
vec.begin()+(vec.size()-1) // last
Далі наведено приклад типового шаблону доступу (більш ранні версії C ++):
int sum = 0;
using Iter = std::vector<int>::const_iterator;
for (Iter it = vec.begin(); it!=vec.end(); ++it) {
sum += *it;
}
Перевага використання ітератора полягає в тому, що ви можете застосувати один і той же візерунок до інших контейнерів :
sum = 0;
for (Iter it = lst.begin(); it!=lst.end(); ++it) {
sum += *it;
}
З цієї причини створити шаблон шаблону, який буде працювати однаково незалежно від типу контейнера, дуже просто . Ще одна перевага ітераторів полягає в тому, що він не передбачає, що дані залишаються в пам'яті; наприклад, можна створити ітератор переадресації, який може читати дані з вхідного потоку, або просто генерує дані на льоту (наприклад, генератор діапазону чи випадкових чисел).
Ще один варіант використання std::for_each
і лямбда:
sum = 0;
std::for_each(vec.begin(), vec.end(), [&sum](int i) { sum += i; });
Оскільки C ++ 11 ви можете використовувати, auto
щоб не вказати дуже довге, складне ім'я ітератора типу, як це було раніше (або навіть складніше):
sum = 0;
for (auto it = vec.begin(); it!=vec.end(); ++it) {
sum += *it;
}
Крім того, існує простіший варіант для кожного варіанта:
sum = 0;
for (auto value : vec) {
sum += value;
}
І, нарешті, є також std::accumulate
де потрібно бути обережним, додаєте ви цілі чи числа з плаваючою комою.