Spec-Zone.ru › C++

Требования к именованным итераторам C++: LegacyForwardIterator

LegacyForwardIterator — это LegacyIterator, который позволяет считывать данные из указанного элемента.

В отличие от LegacyInputIterator и LegacyOutputIterator, его можно использовать в многопроходных алгоритмах.

Если LegacyForwardIterator it происходит из Container, то it его value_type совпадает с контейнером, поэтому при обращении (*it) получается value_type контейнера.

Требования

Тип It соответствует LegacyForwardIterator, если

  • Тип It соответствует LegacyInputIterator
  • Тип It соответствует DefaultConstructible
  • Объекты типа It обеспечивают гарантию многократного прохода, описанную ниже
  • Пусть T — тип значения It. Тип std::iterator_traits<It>::reference должен быть либо
  • T& или T&&(с C++11) если It соответствует LegacyOutputIterator (It — изменяемый), или
  • const T& или const T&&(с C++11) в противном случае (It — постоянный),
(где T — тип, обозначаемый std::iterator_traits<It>::value_type)
  • Сравнение на равенство и неравенство определено для всех итераторов одной и той же основной последовательности и для итераторов, инициализированных значением(с C++14).

И, учитывая

  • i, разрешаемое lvalue типа It
  • reference, тип, обозначаемый std::iterator_traits<It>::reference

Следующие выражения должны быть допустимы и иметь указанные эффекты

Выражение Тип возвращаемого значения Эквивалентное выражение
i++ It It ip = i; ++i; return ip;
*i++ reference

Изменяемый LegacyForwardIterator — это LegacyForwardIterator, который дополнительно удовлетворяет требованиям LegacyOutputIterator.

Гарантия многократного прохода

Учитывая a и b, разрешаемые итераторы типа It:

  • Если a и b равны (a == b контекстуально преобразуется в true) , то либо они оба неразрешаемые, либо *a и *b являются ссылками, привязанными к одному объекту.
  • Если *a и *b ссылаются на один и тот же объект, то a == b.
  • Присваивание через изменяемый ForwardIterator итератор не может сделать итератор недействительным (явный, так как reference определен как ссылка).
  • Инкрементирование копии a не изменяет значение, считанное из a (формально, либо It — тип сырой указателя, либо выражение (void)++It(a), *a эквивалентно выражению *a).
  • a == b подразумевает ++a == ++b.

Итераторы-исключения

Инициализированный значением LegacyForwardIterator ведет себя как итератор "после конца" некоторого неопределенного пустого контейнера: он сравнивается с любым другими инициализированными значением LegacyForwardIterator того же типа.
(с C++14)

Концепция

Для определения std::iterator_traits, определена следующая концепция, предназначенная только для пояснения.

template<class It>
concept __LegacyForwardIterator =
    __LegacyInputIterator<It> && std::constructible_from<It> &&
    std::is_reference_v<std::iter_reference_t<It>> &&
    std::same_as<
        std::remove_cvref_t<std::iter_reference_t<It>>,
        typename std::indirectly_readable_traits<It>::value_type> &&
    requires(It it) {
        {  it++ } -> std::convertible_to<const It&>;
        { *it++ } -> std::same_as<std::iter_reference_t<It>>;
    };

где концепция, предназначенная только для пояснения __LegacyInputIterator<T>, описывается в LegacyInputIterator#Concept.

(с C++20)

Примечания

В отличие от концепции std::forward_iterator, требования LegacyForwardIterator требуют, чтобы обращение возвращало ссылку.

Отчеты об ошибках

Следующие исправляющие ошибки отчеты были применены ретроактивно к ранее опубликованным стандартам C++.

DR Применяется к Поведение, опубликованное Правильное поведение
LWG 1212
(N3066)
C++98 тип возвращаемого значения *i++ не соответствовал типу возвращаемого
значения *i-- , требуемому LegacyBidirectionalIterator
изменен тип возвращаемого
значения на reference
LWG 1311
(N3066)
C++98 'a == b подразумевает ++a == ++b' не гарантирует многопроходность[1] также требуется 'a == b подразумевает ++a != b'[2]
LWG 3798 C++20 __LegacyForwardIterator требуется
std::iter_reference_t<It> быть типом ссылки lvalue
также допускаются типы ссылок rvalue
  1. В сценарии, где a и b используют один и тот же базовый итератор, вычисление выражения ++a == ++b фактически дважды инкрементирует базовый контейнер, но результат по-прежнему true.
  2. Формально также требует подразумевания ++b != a.

См. также

forward_iterator
(C++20)
уточняет, что input_iterator является итератором прямого доступа, поддерживает сравнение на равенство и многопроходность
(концепция)
Библиотека итераторов предоставляет определения для итераторов, свойств итераторов, адаптеров и вспомогательных функций

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/named_req/ForwardIterator

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API