std:: reverse_iterator
|
Определено в заголовочном файле
<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()
из
контейнеров стандартной библиотеки
.
Содержание |
Вложенные типы
|
(до C++20) | ||||||||||||||||
|
(начиная с C++20) |
- ↑ 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)
|
обменивает объекты, на которые указывают два скорректированных базовых итератора
(шаблон функции) |
|
(C++14)
|
создаёт
std::reverse_iterator
с типом, выведенным из аргумента
(шаблон функции) |
Вспомогательные шаблоны
|
template
<
class
Iterator1,
class
Iterator2
>
requires
(
!
std::
sized_sentinel_for
<
Iterator1, Iterator2
>
)
|
(начиная с 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
Смотрите также
|
(C++14)
|
создаёт
std::reverse_iterator
с типом, выведенным из аргумента
(шаблон функции) |
|
(устарело в C++17)
|
базовый класс для упрощения определения требуемых типов для простых итераторов
(шаблон класса) |