Namespaces
Variants

std:: reverse_iterator

From cppreference.net
Iterator library
Iterator concepts
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 Iter >
class reverse_iterator ;

std::reverse_iterator — это адаптер итератора, который меняет направление заданного итератора, который должен быть как минимум LegacyBidirectionalIterator или моделировать bidirectional_iterator (начиная с C++20) . Другими словами, при предоставлении двунаправленного итератора, std::reverse_iterator создаёт новый итератор, который перемещается от конца к началу последовательности, определённой базовым двунаправленным итератором.

Для обратного итератора r , созданного из итератора i , соотношение & * r == & * ( i - 1 ) всегда true (при условии, что r является разыменуемым ); таким образом, обратный итератор, созданный из итератора «за последним элементом», разыменовывается в последний элемент последовательности.

Это итератор, возвращаемый функциями-членами rbegin() и rend() из контейнеров стандартной библиотеки .

range-rbegin-rend.svg

Содержание

Вложенные типы

Тип Определение
iterator_type Iter
iterator_category std:: iterator_traits < Iter > :: iterator_category [1]
value_type std:: iterator_traits < Iter > :: value_type [1]
difference_type std:: iterator_traits < Iter > :: difference_type
pointer std:: iterator_traits < Iter > :: pointer
reference std:: iterator_traits < Iter > :: reference
(до C++20)
Тип Определение
iterator_type Iter
iterator_concept
iterator_category
value_type std:: iter_value_t < Iter >
difference_type std:: iter_difference_t < Iter >
pointer std:: iterator_traits < Iter > :: pointer
reference std:: iter_reference_t < Iter >
(начиная с C++20)
  1. 1.0 1.1 Определение предоставляется специализацией базового std::iterator до C++17.

Члены данных

Участник Описание
Iter current базовый итератор
(защищённый объект-член)

Функции-члены

создает новый reverse_iterator
(public member function)
присваивает другой reverse_iterator
(public member function)
получает доступ к базовому итератору
(public member function)
получает доступ к указываемому элементу
(public member function)
получает доступ к элементу по индексу
(public member function)
перемещает вперед или назад reverse_iterator
(public member function)

Функции, не являющиеся членами класса

сравнивает базовые итераторы
(шаблон функции)
продвигает итератор
(шаблон функции)
вычисляет расстояние между двумя адаптерами итераторов
(шаблон функции)
(C++20)
преобразует результат разыменования скорректированного базового итератора в соответствующий тип rvalue-ссылки
(функция)
(C++20)
обменивает объекты, на которые указывают два скорректированных базовых итератора
(шаблон функции)
создаёт std::reverse_iterator с типом, выведенным из аргумента
(шаблон функции)

Вспомогательные шаблоны

template < class Iterator1, class Iterator2 >

requires ( ! std:: sized_sentinel_for < Iterator1, Iterator2 > )
inline constexpr bool disable_sized_sentinel_for

< std :: reverse_iterator < Iterator1 > , std :: reverse_iterator < Iterator2 >> = true ;
(начиная с C++20)

Эта частичная специализация std::disable_sized_sentinel_for предотвращает удовлетворение специализациями reverse_iterator концепции sized_sentinel_for если их базовые итераторы не удовлетворяют данной концепции.

Возможная реализация

Ниже представлена частичная реализация, фокусирующаяся на способе хранения внутреннего итератора, вызывающая std::prev только тогда, когда содержимое извлекается через operator * .

template<class It>
class reverse_iterator
{
protected:
    It current = It();
public:
    reverse_iterator() = default;
    constexpr explicit reverse_iterator(It itr) : current(itr) {}
    template<class U>
        requires (!std::is_same_v<U, It> && std::convertible_to<const U&, It>)
    constexpr explicit reverse_iterator(const U& other) : current(other.base()) {}
    constexpr decltype(auto) operator*() const
    {
        return *std::prev(current); // <== возвращает содержимое предыдущего элемента
    }
    constexpr reverse_iterator& operator++() { --current; return *this; }
    constexpr reverse_iterator operator++(int) { auto tmp = *this; ++(*this); return tmp; }
    constexpr reverse_iterator& operator--() { ++current; return *this; }
    constexpr reverse_iterator operator--(int) { auto tmp = *this; --(*this); return tmp; }
    constexpr It base() const { return current; }
    // Другие функции-члены, дружественные функции и определения типов не показаны здесь.
};

Примечания

std::reverse_iterator не работает с итераторами, разыменование которых возвращает ссылку на член * this (так называемые «stashing iterators»). Примером такого итератора является MSVC STL's std::filesystem::path::iterator .

Пример

#include <cstddef>
#include <iostream>
#include <iterator>
template<typename T, std::size_t SIZE>
class Stack
{
    T arr[SIZE];
    std::size_t pos = 0;
public:
    T pop()
    {
        return arr[--pos];
    }
    Stack& push(const T& t)
    {
        arr[pos++] = t;
        return *this;
    }
    // мы хотим, чтобы перебор элементов Stack происходил в порядке LIFO
    // поэтому используем std::reverse_iterator как адаптер для существующих итераторов
    // (которые в данном случае являются простыми указателями: [arr, arr + pos)
    auto begin() { return std::reverse_iterator(arr + pos); }
    auto end() { return std::reverse_iterator(arr); }
};
int main()
{
    Stack<int, 8> s;
    s.push(5).push(15).push(25).push(35);
    for (int val : s)
        std::cout << val << ' ';
    std::cout << '\n';
}

Вывод:

35 25 15 5

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

создаёт std::reverse_iterator с типом, выведенным из аргумента
(шаблон функции)
(устарело в C++17)
базовый класс для упрощения определения требуемых типов для простых итераторов
(шаблон класса)