Junior
178
questionbank
Какие виды итераторов ты знаешь?
Ответ от нейросети
sobes.tech AI
Итераторы в C++ представляют собой обобщенные указатели, предоставляющие доступ к элементам контейнера и возможность их обхода. Согласно стандарту C++, различают 5 основных категорий итераторов, упорядоченных по возрастанию их возможностей:
- Input iterators (Входные итераторы):
- Позволяют только чтение элементов (
operator*() const). - Позволяют инкрементировать итератор (
operator++()). - Поддерживают сравнение на равенство (
operator==(),operator!=()). - Пример: итераторы для потоков ввода (
std::istream_iterator).
- Позволяют только чтение элементов (
- Output iterators (Выходные итераторы):
- Позволяют только запись элементов (
operator*()). - Позволяют инкрементировать итератор (
operator++()). - Пример: итераторы для потоков вывода (
std::ostream_iterator).
- Позволяют только запись элементов (
- Forward iterators (Однонаправленные итераторы):
- Поддерживают все возможности входных и выходных итераторов.
- Гарантируют, что инкрементирование итератора всегда ведет к следующему элементу или концу последовательности.
- Пример: итераторы для односвязных списков (
std::forward_list).
- Bidirectional iterators (Двунаправленные итераторы):
- Поддерживают все возможности однонаправленных итераторов.
- Позволяют декрементировать итератор (
operator--()) для перемещения к предыдущему элементу. - Пример: итераторы для списков (
std::list) и множеств (std::set).
- Random access iterators (Итераторы произвольного доступа):
- Поддерживают все возможности двунаправленных итераторов.
- Позволяют выполнять арифметические операции с итераторами (сложение/вычитание целых чисел, вычитание итераторов) для быстрого перехода к любому элементу.
- Позволяют использовать оператор
[]для доступа к элементам по индексу. - Пример: итераторы для векторов (
std::vector) и массивов (std::array).
Эта иерархия подразумевает, что каждая последующая категория итераторов обладает возможностями всех предыдущих. Например, итератор произвольного доступа также является двунаправленным, однонаправленным, входным и выходным.
#include <vector>
#include <list>
#include <forward_list>
#include <iostream>
#include <iterator>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// Random access iterator
auto vec_it = vec.begin();
vec_it += 2; // Произвольный доступ
std::cout << *vec_it << std::endl; // Вывод: 3
std::list<int> lst = {10, 20, 30};
// Bidirectional iterator
auto list_it = lst.begin();
++list_it; // Инкремент
--list_it; // Декремент
std::forward_list<int> flst = {100, 200, 300};
// Forward iterator
auto flist_it = flst.begin();
++flist_it; // Только инкремент
// Input iterator
std::istream_iterator<int> input_it(std::cin);
// Output iterator
std::ostream_iterator<int> output_it(std::cout, " ");
return 0;
}
Существуют также адаптеры итераторов (например, std::reverse_iterator, std::move_iterator), которые изменяют поведение базовых итераторов.