Spec-Zone.ru › C++

std::bidirectional_iterator

Определён в заголовочном файле <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 концептов стандартной библиотеки, должны сохранять равенство (кроме случаев, когда указано иное).

Примечания

В отличие от требований LegacyBidirectionalIterator, концепт bidirectional_iterator не требует, чтобы разыменование возвращало lvalue.

Пример

Минимальный двунаправленный итератор.

#include <cstddef>
#include <iterator>

struct SimpleBidiIterator
{
    using difference_type = std::ptrdiff_t;
    using value_type = int;

    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>);

См. также

forward_iterator
(C++20)
задаёт, что input_iterator является прямым итератором, поддерживающим сравнение на равенство и многопроходный обход
(концепт)
random_access_iterator
(C++20)
задаёт, что bidirectional_iterator является итератором произвольного доступа, поддерживающим перемещение за постоянное время и индексирование
(концепт)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/iterator/bidirectional_iterator

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API