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>);
См. также
|
(C++20) | указывает, что тип является входным итератором, то есть его разыменованные значения можно считывать, а сам итератор можно инкрементировать как до, так и после использования (концепция) |
|
(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