std:: forward_iterator
|
Определено в заголовочном файле
<iterator>
|
||
|
template
<
class
I
>
concept forward_iterator
=
|
(начиная с 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>);
Смотрите также
|
(C++20)
|
определяет, что тип является итератором ввода, то есть его ссылочные значения могут быть прочитаны и он может быть как пре-, так и постинкрементирован
(concept) |
|
(C++20)
|
определяет, что
forward_iterator
является двунаправленным итератором, поддерживающим перемещение назад
(concept) |