std:: bidirectional_iterator
|
Определено в заголовочном файле
<iterator>
|
||
|
template
<
class
I
>
concept bidirectional_iterator
=
|
(начиная с C++20) | |
Концепт
bidirectional_iterator
расширяет
forward_iterator
, добавляя возможность перемещения итератора в обратном направлении.
Содержание |
Определение концепции итератора
Определение этой концепции задаётся с помощью экспозиционно-ограниченного псевдонима шаблона /*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:: bidirectional_iterator_tag > равно true .) - В противном случае /*ITER_CONCEPT*/ < I > не обозначает тип и приводит к ошибке подстановки.
Семантические требования
Двунаправленный итератор
r
называется
декрементируемым
тогда и только тогда, когда существует такой
s
, что
++
s
==
r
.
std
::
bidirectional_iterator
<
I
>
моделируется только в том случае, если все подразумеваемые им концепты моделируются, и при наличии двух объектов
a
и
b
типа
I
:
-
Если
aявляется декрементируемым,aнаходится в области определения выражений -- a и a -- . - Префиксный декремент возвращает lvalue, ссылающееся на операнд: std:: addressof ( -- a ) == std:: addressof ( a ) .
- Постфиксный декремент возвращает предыдущее значение операнда: если bool ( a == b ) , тогда bool ( a -- == b ) .
- Постфиксный и префиксный декремент выполняют одинаковое изменение операнда: Если bool ( a == b ) , тогда после вычисления как a -- , так и -- b , bool ( a == b ) всё ещё выполняется.
- Инкремент и декремент являются обратными операциями друг для друга:
-
-
Если
aинкрементируем и bool ( a == b ) , тогда bool ( -- ( ++ a ) == b ) . -
Если
aдекрементируем и bool ( a == b ) , тогда bool ( ++ ( -- a ) == b ) .
-
Если
Сохранение равенства
Выражения, объявленные в requires выражениях концепций стандартной библиотеки, должны быть equality-preserving (если не указано иное).
Примечания
В отличие от
LegacyBidirectionalIterator
требований, концепт
bidirectional_iterator
не требует, чтобы разыменование возвращало lvalue.
Пример
Минимальный двунаправленный итератор.
#include <cstddef> #include <iterator> class SimpleBidiIterator { public: using difference_type = std::ptrdiff_t; using value_type = int; SimpleBidiIterator(); SimpleBidiIterator(const SimpleBidiIterator&); SimpleBidiIterator& operator=(const SimpleBidiIterator&); int operator*() const; SimpleBidiIterator& operator++(); SimpleBidiIterator operator++(int) { auto tmp = *this; ++*this; return tmp; } SimpleBidiIterator& operator--(); SimpleBidiIterator operator--(int) { auto tmp = *this; --*this; return tmp; } bool operator==(const SimpleBidiIterator&) const; }; static_assert(std::bidirectional_iterator<SimpleBidiIterator>);
Смотрите также
|
(C++20)
|
определяет, что
input_iterator
является прямым итератором, поддерживающим сравнение на равенство и многопроходность
(концепт) |
|
(C++20)
|
определяет, что
bidirectional_iterator
является итератором произвольного доступа, поддерживающим продвижение за константное время и индексацию
(концепт) |