Кожному алгоритму, залежно від того, чим він займається, потрібний свій тип ітератора. Якщо потрібно звертатися до довільних елементів ітератора, потрібний ітератор довільного доступу. Якщо ж потрібно просто пересуватися від елемента до елемента, то підійде менш потужний прямий ітератор. В таблиці 10.8 показані приклади алгоритмів та потрібних їм ітераторів.
Таблиця 10.8
Типи ітераторів, потрібні певним алгоритмам
Алгоритм
| Вхідний
| Вихідний
| Прямий
| Двонапрямлений
| Довільного доступу
|
for_each
| *
|
|
|
|
|
find
| *
|
|
|
|
|
count
| *
|
|
|
|
|
copy
| *
| *
|
|
|
|
replace
|
|
| *
|
|
|
unique
|
|
| *
|
|
|
reverse
|
|
|
| *
|
|
sort
|
|
|
|
| *
|
nth_element
|
|
|
|
| *
|
merge
| *
|
|
|
|
|
accumulate
| *
|
|
|
|
|
Попри те, що кожному алгоритму потрібний певний рівень можливостей, потужніші ітератори теж працюватимуть нормально. Алгоритму replace() потрібний прямий ітератор, але він працюватиме і з двонапрямленим ітератором, і з ітератором довільного доступу.
Завдяки двом попереднім таблицям, можна встановити, з якими алгоритмами працює той чи інший ітератор. Наприклад, алгоритму sort() потрібний ітератор довільного доступу. Ітератор довільного доступу працює з векторами і чергами з двостороннім доступом. Отже, алгоритм sort() працюватиме лише з ними.
Будь-який алгоритм, якому не потрібний ітератор довільного доступу, працюватиме з довільним типом контейнера STL, оскільки всі контейнери використовують двонапрямлені ітератори, які тільки на один рівень менш потужні, ніж ітератори довільного доступу. Якщо б у STL існували однозв’язні списки, то з ними можна було б користуватися прямими ітераторами, але не можна б було використовувати ітератор reverse().
Як бачимо, відносно мале число алгоритмів реально потребує алгоритмів довільного доступу. Тому більшість алгоритмів працюватиме з більшістю контейнерів.
Перекриття методів та алгоритмів
Інколи доводиться вибирати між методами та алгоритмами з однаковими іменами. Наприклад, алгоритму find() потрібний тільки вхідний ітератор, тому він може використовуватися з будь-яким контейнером. Але у множин і відображень є свій власний метод find() (чого немає у послідовних контейнерів). Яку ж версію find() слід вибрати? В загальному випадку, якщо вже наявний метод, що дублює своєю назвою алгоритм, то це зроблено тому, що алгоритм у даному випадку неефективний. Тому, напевно, при наявності такого вибору краще звернутися до методу.
Робота з ітераторами
Використовувати ітератори значно простіше, ніж розповідати про них. Розглянемо, як реально використовуються ітератори з тими чи іншими функціями.