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) |
- До C++17 определение предоставляется базовой специализацией
std::iterator.
Члены данных
| Член | Описание |
|---|---|
Iter current | базовый итератор (защищённый объект-член) |
Функции-члены
создаёт новый reverse_iterator (открытая функция-член) |
|
присваивает другой reverse_iterator (открытая функция-член) |
|
| получает доступ к базовому итератору (открытая функция-член) |
|
| получает доступ к элементу, на который указывает итератор (открытая функция-член) |
|
| получает доступ к элементу по индексу (открытая функция-член) |
|
перемещает reverse_iterator вперёд или назад (открытая функция-член) |
Функции, не являющиеся членами
|
(C++20) | сравнивает базовые итераторы (шаблон функции) |
| перемещает итератор вперёд (шаблон функции) |
|
| вычисляет расстояние между двумя адаптерами итераторов (шаблон функции) |
|
|
(C++20) | приводит результат разыменования скорректированного базового итератора к соответствующему типу rvalue-ссылки (функция) |
|
(C++20) | меняет местами объекты, на которые указывают два скорректированных базовых итератора (шаблон функции) |
|
(C++14) | создаёт 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); // <== returns the content of prev
}
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; }
// Other member functions, friend functions, and member typedefs are not shown here.
};
|
Примечания
std::reverse_iterator не работает с итераторами, разыменование которых возвращает ссылку на член *this (так называемыми «итераторами с сохранением значения»). Пример такого итератора — std::filesystem::path::iterator в MSVC STL.
Пример
#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;
}
// we wish that looping on Stack would be in LIFO order
// thus we use std::reverse_iterator as an adaptor to existing iterators
// (which are in this case the simple pointers: [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) | базовый класс, упрощающий определение требуемых типов для простых итераторов (шаблон класса) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/iterator/reverse_iterator