Namespaces
Variants

std:: forward_iterator

From cppreference.net
Iterator library
Iterator concepts
forward_iterator
(C++20)


Iterator primitives
Algorithm concepts and utilities
Indirect callable concepts
Common algorithm requirements
(C++20)
(C++20)
(C++20)
Utilities
(C++20)
Iterator adaptors
Range access
(C++11) (C++14)
(C++14) (C++14)
(C++11) (C++14)
(C++14) (C++14)
(C++17) (C++20)
(C++17)
(C++17)
Определено в заголовочном файле <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)

Этот концепт уточняет std::input_iterator , требуя, чтобы I также моделировал std::incrementable (тем самым делая его пригодным для многопроходных алгоритмов), и гарантируя, что два итератора одного диапазона могут быть сравнены друг с другом.

Содержание

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

Определение этой концепции задаётся с помощью экспозиционно-ограниченного псевдонима шаблона /*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>
class SimpleForwardIterator
{
public:
    using difference_type = std::ptrdiff_t;
    using value_type = int;
    SimpleForwardIterator();
    SimpleForwardIterator(const SimpleForwardIterator&);
    SimpleForwardIterator& operator=(const SimpleForwardIterator&);
    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>);

Смотрите также

определяет, что тип является итератором ввода, то есть его ссылочные значения могут быть прочитаны и он может быть как пре-, так и постинкрементирован
(concept)
определяет, что forward_iterator является двунаправленным итератором, поддерживающим перемещение назад
(concept)