Ітератори

Розуміння ітераторів є ключовим для вивчення STL в цілому та усвідомлення того, як найкраще використовувати бібліотеку STL. Параметричні алгоритми STL написані в термінах ітераторних параметрів, а контейнери STL забезпечують можливості ітераторів в алгоритмах. Ітератори відіграють роль «дротів» при з’єднанні. Найпростішим ітератором є звичайний покажчик мови С++, але можна визначити і багато інших ітераторів. Проте від цих інших ітераторів вимагається, щоб вони поводили себе, як покажчики відносно таких операцій, як ++ або *, у тому сенсі, що ++і пересуває ітератор і на наступний елемент, а * і видає значення елемента, відповідного ітератору і.

Розглянемо параметричну функцію accumulate, викликану з ітераторами first і beyond та значенням init:

accumulate(first, beyond, init);

вона підсумовує зі значенням init значення елементів, доступних за інтератором, починаючи з елемента, відповідного значенню ітератора first, та закінчуючи елементом, відповідним значенню ітератора, яке є попереднім beyond, та як результат повертає здобуту суму. Наприклад, можна дописати таку програму, яка обчислює та друкує суму елементів вектора:

#include

#include

#include

int main ()

{

cout <<« Параметрична функція accumulate.»<< end1;

int x[5] = {2,3,5,7,11};

//ініціалізація вектора vector1 значеннями від х[0] до х[4]

vector vector1(&x[0], &x[5]);

int sum = accumulate(vector1.begin(),vector1.end(),0);

assert (sum == 28);

}

Ця програма використовує функцію accumulate для додавання цілих значень з вектора vector1, який розглядається за допомогою ітераторів vector1.begin( ) та vector1 .end ( ). Можна також застосовувати функцію accumulate до масиву х:

sum = accumulate (&x[0], &x[5], 0);

чи, наприклад, до списку значень типу подвійної точності (double):

double y[5] = {2.0, 3.0, 5.0 ,7.0, 11.0};

list = list1(&y[0], &y[5]);

sum = accumulate(list1.begin(),list1.end(),0.0);



У кожному із цих випадків абстрактний зміст один і той самий — додавання початкового значення до всіх значень послідовностей.

Розглянемо докладніше спосіб використання ітераторів функцією accumulate. Цю функцію можна визначити так:

template

T accumulate(InputIterator first, InputIterator beyond, T init)

{

while (first != beyond)

init = init + *first++;

return init;

}

У ній над ітераторами виконуються лише операція збільшення на 1 (постфіксна операція ++), операція розіменування * та операція перевірки на нерівність !=. Лише ці операції, а також префіксна операція ++ та операція перевірки на рівність = = вимагають категорії ітераторів, які називають ітераторами вводу (input iterators). Ще однією характеристикою ітераторів вводу, від якої вони дістали свою назву, є те, що від операції * вимагається лише одне: вона має читати з контейнера, але не записувати до нього. Ітератори виводу (output iterators) використовують ту саму операцію *, але тільки для запису даних в контейнер, а не для читання з нього.

У STL визначені ще три категорії ітераторів: прямі ітератори (forward iterators), двонапрямлені ітератори (bidirectional iterators) та ітератори вільного доступу (random access iterators). Між цими категоріями ітераторів встановлені ієрархічні відношення. Це означає, що кожна категорія ітераторів накладає нові вимоги на ітератори попередньої категорії, оскільки ітератор кожної категорії є одночасно ітератором всіх попередніх щодо неї за ієрархією категорій. Наприклад, двонапрямлений ітератор є також і прямим ітератором, а ітератор довільного доступу є також і прямим ітератором, а ітератор довільного доступу є також двонапрямленим та прямим ітератором.

Ступінь параметризованості алгоритмів, що їх використовують ітератори вводу, як, наприклад, accumulate, find та merge, вищий у алгоритмів, які потребують потужніших ітераторів. Це, скажімо, алгоритми sort, якому потрібний ітератор довільного доступу. Алгоритм sort не можна використовувати, наприклад, зі списковим контейнером, оскільки контейнери списку підтримують лише двонап­рямлені ітератори і не підтримують ітераторів довільного доступу. Тому у STL контейнер списку має функцію-член, яка ефективно здійснює сортування, використовуючи двонапрямлені ітератори.


0384055169887997.html
0384100572905782.html
    PR.RU™