Spec-Zone.ru › C++

std::forward_iterator

Определён в заголовочном файле <iterator>
template< class I >
    concept forward_iterator =
        std::input_iterator<I> &&
        std::derived_from</*ITER_CONCEPT*/<I>, std::forward_iterator_tag> &&
        std::incrementable<I> &&
        std::sentinel_for<I, I>;
(начиная с C++20)

This concept refines std::input_iterator by requiring that I also model std::incrementable (thereby making it suitable for multi-pass algorithms), and guaranteeing that two iterators to the same range can be compared against each other.

Определение концепции итератора

Определение этой концепции задаётся с помощью шаблона псевдонима /*ITER_CONCEPT*/, используемого только для пояснения.

Чтобы определить /*ITER_CONCEPT*/<I>, пусть ITER_TRAITS<I> обозначает I, если специализация std::iterator_traits<I> создана на основе первичного шаблона, и std::iterator_traits<I> в противном случае:

  • Если ITER_TRAITS<I>::iterator_concept корректно и обозначает тип, /*ITER_CONCEPT*/<I> обозначает этот тип.
  • В противном случае, если ITER_TRAITS<I>::iterator_category корректно и обозначает тип, /*ITER_CONCEPT*/<I> обозначает этот тип.
  • В противном случае, если std::iterator_traits<I> создан на основе первичного шаблона, /*ITER_CONCEPT*/<I> обозначает std::random_access_iterator_tag.
    (То есть предполагается, что std::derived_from</*ITER_CONCEPT*/<I>, std::forward_iterator_tag> является true.)
  • В противном случае /*ITER_CONCEPT*/<I> не обозначает тип и приводит к сбою подстановки.

Семантические требования

I моделирует std::forward_iterator тогда и только тогда, когда I моделирует все концепции, которые он включает, и для объектов i и j типа I:

  • Сравнение итераторов i и j имеет определённый результат, если
    • i и j являются итераторами одной и той же базовой последовательности, или
    • и i, и j инициализированы значением по умолчанию; в этом случае они равны.
  • Указатели и ссылки, полученные из итератора прямого хода для диапазона, остаются действительными, пока существует этот диапазон.
  • Если i и j допускают разыменование, они обеспечивают гарантию многократного прохода, то есть:
    • i == j влечёт ++i == ++j, и
    • ((void)[](auto x){ ++x; }(i), *i) эквивалентно *i.

Примечания

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

Пример

Минимальный итератор прямого хода.

#include <cstddef>
#include <iterator>

struct SimpleForwardIterator
{
    using difference_type = std::ptrdiff_t;
    using value_type = int;

    int operator*() const;

    SimpleForwardIterator& operator++();

    SimpleForwardIterator operator++(int)
    {
        auto tmp = *this;
        ++*this;
        return tmp;
    }

    bool operator==(const SimpleForwardIterator&) const;
};

static_assert(std::forward_iterator<SimpleForwardIterator>);

См. также

input_iterator
(C++20)
указывает, что тип является входным итератором, то есть его разыменованные значения можно считывать, а сам итератор можно инкрементировать как до, так и после использования
(концепция)
bidirectional_iterator
(C++20)
указывает, что forward_iterator является двунаправленным итератором, поддерживающим перемещение назад
(концепция)

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

Spec-Zone.ru

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