STL Итераторы Категории итераторов

В продолжении знакомства с итераторами имеет смысл посмотреть на различные категории итераторов
Итераторы подчиняются принципу чистой абстракции, то есть любой объект, который ведет себя как итератор, является итератором
Категории итераторов

  • Итераторы ввода и вывода
  • Однонаправленные итераторы и двунаправленные итераторы
  • Итераторы произвольного доступа
  • Вспомогательные итераторы
  • Реверсивные итераторы
  • Итераторы потоков
  • Итераторы вставки
  • Константный итератор
  • Итератор ввода — Это такой итератор, который перемещается только вперед и поддерживает только чтение.
  • Итератор ввода — самая простая разновидность итераторов. Доступны такие итераторы только для чтения. Чтобы узнать прочтенный элемент, к итератору применяется оператор разыменования (как с указателем).Иногда может потребоваться узнать указывают ли два итератора ввода на один и тот же объект, для этого разрешено сравнивать два итератора ввода между собой. Вместо итератора ввода может подставляться любой основной итератор кроме итератора вывода

    Самый простой пример использования итератора ввода (в моем представлении) — вывести на экран элементы массива с помощью итератора ввода

    for_each — это алгоритм. Алгоритм for_each принимает указатель на начало массива, указатель на первый элемент за границей массива и указатель на функцию. Не путайте саму функцию с указателем на нее. Кто не понял причем тут итератор, читать самые самые первые строки. Еще может кому-то не очень понятен параметр num. В этот параметр записывается значение, которое получил алгоритм for_each

    Еще как пример можно взять пример заполнения контейнера STL из текстового файла используя итератор ввода

    Может возникнуть вопрос: «что такое istreambuf_iterator?» Это почти такой же итератор, как istream_iterator.

    А что такое istream_iterator? — Это итератор входного потока. Читает (используя operator <<) последовательные элементы из входного потока, для которого он был создан Чтобы никто не запутался уточним

    • istream_iterator — итератор для чтения элементов из входного потока (использует оператор <<).
    • streambuf_iterator — итератор, похож на istream_iterator и работает аналогично, но объекты итератора istream_iterator обращаются прямо к буферу потока и непосредственно читают следующий символ

    Приблизительно так: Первый считает до первого пробела в потоке, второй считает весь поток.

    Невозможно записывать что-либо с использованием входных итераторов
    =======================================
    Итераторы вывода — это противоположность итераторам ввода. Служат они для ссылки на область памяти,
    куда выводятся данные. Разыменовывать такие итераторы нужно только для того, чтобы присвоить некое значение объекту, на который итератор ссылается. Итераторы ввода могут быть возвращены итераторами потоков вывода (ostream_iterator) и итераторами вставки inserter, front_inserter и back_inserter

    Как и в первом случае, приведу два примера. Для массива и для файла

    Итератор вывода Вывести все элементы контейнера на экран

    Код С++ С помощью итератора вывода записать в файл данные контейнера STL

    Этот код не запишет строчки а запишет все 1,2,3 в одну строку, чтобы все записалось построчно нужно в самом массиве добавить признаки окончания строки.

    Разумеется работать можно не только с файлами. С любыми потоками. Используем итератор вывода для вывода всех элементов вектора на экран. Похожее уже было,но мало ли кто не понял. Выводим элементы вектора в поток cout

    ============================================
    Не путайте copy с итератором, copy — это алгоритм и for_each тоже алгоритм.

    • Если объединить итератор ввода и итератор вывода, то получится однонаправленный итератор.
    • Однонаправленный итератор это итератор, который поддерживает чтение и запись адресуемого элемента.

    Как один из понятных примеров могу привести пример поиска элемента в массиве

    Чтобы немного конкретизировать поясню. Сначала мы запоминаем значение в x, потом это значение вводим
    в алгоритм find как один из параметров. После этого алгоритм ищет этот введенный элемент x в указанном диапазоне. Если поиски были удачны, то выводим прочитанный алгоритмом элемент на экран с добавлением «найдено», если же поиски неудачны, то попытки вывести элемент (presult) с очень большой вероятностью вернет мусор. Так как для одного и того же алгоритма были произведены и ввод в алгоритм и вывод элемента из алгоритма, при этом происходил последовательный перебор элементов, то согласно определению это можно называть однонаправленным итератором

    Еще один пример однонаправленного итератора — использование алгоритма replace. Проведем небольшую
    перестановку в массиве

    Алгоритм replace читает значения, изменяет их и перемещается от одного к другому. Есть и другие примеры, но те, кто не очень понял, лучшее понимание прийдет со временем, главное заниматься

    ==================================
    Двунаправленные итераторы аналогичны однонаправленным и широко применяются в реверсивных алгоритмах

    Код С++ двунаправленный итератор

    Итераторы контейнерных классов list, set, multiset, map и multimap являются двунаправленными.

    Двунаправленные итераторы способны перемещаться в обоих направлениях благодаря инкременту (++) и декременту (--)
    ===================================
    Итераторы произвольного доступа. Такие итераторы имеют большие возможностей по сравнению со всеми
    остальными основными итераторами. Использование таких итераторов очень и очень сильно похоже на арифметику указателей.

    Т.е итераторы произвольного доступа это такие итераторы, которые не только дают легко обращаться к произвольному элементу. Несмотря на то, что мы изменяем итератор переприсваиванием в него значения, на контейнер это никак не влияет.
    ===========================
    Реверсивные итераторы. Надеюсь с понятием реверсивный вы знакомы (это как задом наперед). Получить
    реверсивный итератор для контейнера можно вызовом метода rbegin, а реверсивное значение «за пределом» возвращается методом rend

    Код С++ нормальный и реверивный итераторы

    =============================
    Итераторы вставки. Перебор перебором, но иногда требуется вставить элемент вначало, в хвост или в середину контейнера. Вот такая вставка в середину контейнера может быть проблематичной с перечисленными уже итераторами. Вместо того, чтобы занять новое место скорее получится затереть уже существующий элемент и встать на его место, чтобы такого не случилось как раз нужны итераторы вставки.

    Пример со списком

    Надеюсь комментарии дадут все понять, итак много как-то вышло написать.
    ==================
    Еще есть константный итератор. Константный итератор не допускает изменения данных, на которые он ссылается. Можно считать константный итератор указателем на константу

    Вот такое вот знакомство с итераторами получилось. В принципе не очень сложно, но и не сказать, что совсем просто. Много непонятных моментов, много моментов, которые могут запутать. Главное заниматься и все станет на свои места. Цель этого материала не досконально объяснить итераторы, а дать обобщенное понятие, чтоб было легче ориентироваться в понятиях итераторов. Досконально объяснить я все равно не могу.

    Допишу сюда небольшую таблицу

    Итератор Описание
    для чтения Читают значения с движением вперед. Могут быть инкрементированы, сравнены и разыменованы.
    для записи Пишут значения с движением вперед. Могут быть инкрементированы и разыменованы.
    однонаправленные Читают или пишут значения с движением вперед. Комбинируют функциональность предыдущих двух типов с возможностью сохранять значение итератора.
    двунаправленные Читают и пишут значения с движением вперед или назад. Похожи на однонаправленные, но их также можно инкрементировать и декрементировать.
    с произвольным доступом Читают и пишут значения с произвольным доступом. Самые мощные итераторы, сочетающие функциональность двунаправленных итераторов и возможность выполнения арифметики указателей и сравнений указателей.
    обратные Или итераторы с произвольным доступом, или двунаправленные, движущиеся в обратном направлении.

    Итераторы для существующих элементов в контейнере могут стать недействительными, при изменении контейнера. Это делает изменение контейнера при итерациях проблематичной. Контейнеры предлагают различные гарантии в этой связи:
    vectors: вставка / удаление может аннулировать все итераторы.
    list/map: удаление делает недействительными только итераторы на удаленный элемент(ы), но не на другие элементы.

    Все комментарии на сайте проверяются, поэтому ваш комментарий может появиться не сразу. Для вставки кода в комментарий используйте теги: [php]ВАШ_КОД[/php]

    3 комментария: STL Итераторы Категории итераторов

    • Василь говорит:

      Прошу прощения, что-то с тегами не вышло 🙂

      Автор сайта отвечает:
      как-то неправильно выразились. Второе наверное "помещает во"




      0



      0
    • Marry говорит:

      А можно такой же разбор только с List?

      Я понимаю, что там всё похоже, но всё же.

      И желательно, чтобы использовалась структура, а не целые числа/чаровский массив.

      Буду очень признательна!




      0



      0
    • Cast говорит:

      Первый пример, строка 14




      0



      0

    Добавить комментарий

    Ваш e-mail не будет опубликован.

    Поиск

     
         

    Случайная книга в электронном формате

    https://www.litres.ru/aleksandr-zholobov/stanki-s-chpu-ustroystvo-programmirovanie-instrumentalnoe-obespechenie-i-osnastka-6715493/?lfrom=15589587
    Яндекс.Метрика
    НАГРАДИ АВТОРА САЙТА
    WEBMONEY
    R375024497470
    U251140483387
    Z301246203264
    E149319127674
    
    
    Подождите, идет подготовка к зависанию компьютера...

    Выражаю свою признательность

    • Максиму очень признателен за указание на мои ошибки и неточности.
    • Sergio ===> за оказание помощи в исправлении моих ошибок
    • Gen ===> за правильное стремление помочь другим новичкам и выявления моих ошибок