Namespaces
Variants

std:: bidirectional_iterator

From cppreference.net
Iterator library
Iterator concepts
bidirectional_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 bidirectional_iterator =
std:: forward_iterator < I > &&
std:: derived_from < /*ITER_CONCEPT*/ < I > , std:: bidirectional_iterator_tag > &&
requires ( I i ) {
{ -- i } - > std:: same_as < I & > ;
{ i -- } - > std:: same_as < I > ;

} ;
(начиная с 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>);

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

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