Ответ
Forward iterator (однонаправленный итератор) — это одна из категорий итераторов в C++, которая расширяет возможности input_iterator и output_iterator. Он гарантирует возможность многократного прохода по одному и тому же диапазону и сохранение валидности других итераторов на ту же последовательность при инкременте.
Требования (концепт std::forward_iterator с C++20):
- Поддерживает чтение (
*it) и запись (*it = value) (если не константный). - Допускает инкремент (
++it,it++). - Многопроходность: диапазон можно проходить несколько раз.
- Стабильность ссылок: значение, полученное разыменованием, остаётся валидным до тех пор, пока итератор не инвалидируется другими операциями (например, удалением элемента).
- Поддерживает сравнение на равенство/неравенство (
==,!=).
Контейнеры, использующие forward iterators:
std::forward_liststd::unordered_set,std::unordered_multisetstd::unordered_map,std::unordered_multimap
Пример с std::forward_list:
#include <forward_list>
#include <iostream>
int main() {
std::forward_list<int> flist = {10, 20, 30, 40};
// forward_iterator позволяет проходить по списку только вперёд
for (auto it = flist.begin(); it != flist.end(); ++it) {
std::cout << *it << ' '; // Чтение
*it += 5; // Запись (изменение значения)
}
std::cout << 'n';
// Многопроходность: можно снова пройти по тому же диапазону
for (const auto& val : flist) {
std::cout << val << ' '; // Выведет: 15 25 35 45
}
return 0;
}
Отличие от более мощных итераторов: Forward iterator не поддерживает декремент (--) и арифметику указателей (произвольный доступ), в отличие от bidirectional_iterator (например, у std::list) и random_access_iterator (например, у std::vector).
Ответ 18+ 🔞
Слушай, а вот forward iterator — это такая штука, которая как будто тебе дали одноразовую зажигалку, а ты её можешь чиркать дохуя раз, но только вперёд. В рот мне чих-пых, понимаешь? Он берёт всё от input и output итераторов, но ещё и гарантирует, что если ты прошёл по списку, то можешь вернуться в начало и пройти ещё раз — и ничего не разъёбется. И другие итераторы на эту же коллекцию не накроются медным тазом, пока ты одного из них инкрементируешь.
Что от него хотят (этот концепт std::forward_iterator с C++20):
- Читать (
*it) и писать (*it = value) можно, если он не константный, конечно. - Двигаться вперёд (
++it,it++) — обязательно. - Многопроходность: это не одноразовая сигарета, можно туда-сюда по одному диапазону ходить, пока не надоест.
- Стабильность ссылок: то, на что он указывает, не испарится просто так, пока ты сам контейнер не изуродуешь.
- Сравнивать на равенство (
==,!=) — чтобы понимать, не упёрся ли уже в конец.
Где такое встречается, ёпта:
std::forward_list— односвязный список, туда только вперёд, как в светлое будущее.- Все эти
unordered_контейнеры (множества, мапы) — там внутри каша из бакетов, и порядок хрен поймёшь, но пройти вперёд можно.
Пример с std::forward_list, чтобы было совсем ясно:
#include <forward_list>
#include <iostream>
int main() {
std::forward_list<int> flist = {10, 20, 30, 40};
// forward_iterator — это как идти по рельсам, назад не получится
for (auto it = flist.begin(); it != flist.end(); ++it) {
std::cout << *it << ' '; // Смотрим
*it += 5; // Меняем прямо на ходу
}
std::cout << 'n';
// А вот и многопроходность: по тому же самому списку ещё разок
for (const auto& val : flist) {
std::cout << val << ' '; // Напечатает: 15 25 35 45
}
return 0;
}
Чем он не крут? А тем, что назад шагнуть (--) — ни хуя себе, нельзя. И прыгнуть на 10 элементов вперёд за раз — тоже не выйдет. Это удел более крутых ребят, bidirectional и random access итераторов, которые в std::list и std::vector живут. А этот — просто честный работяга, идёт себе вперёд и не ныть.