# std::ranges::views::reverse, std::ranges::reverse_view

< cpp‎ | ranges

定义于头文件 `<ranges>` |  |
template< ranges::view V > requires ranges::bidirectional_range<V> class reverse_view : public ranges::view_interface<reverse_view<V>> | (1) | (C++20 起)
namespace views { inline constexpr /*unspecified*/ reverse = /*unspecified*/; } | (2) | (C++20 起)

1) 代表有逆序的底层 `view` 的视图。
2) 范围适配器对象。表达式 views::reverse(e) 表达式等价于下列表达式之一，除了只求值 `E` 一次：

- e.base() ，若 e 的类型是（可有 cv 限定的） `reverse_view` 的特化；
- 否则，若 e 的类型是（可有 cv 限定的）某迭代器类型 `I` 和 `ranges::subrange_kind` 类型值 `K` 的 ranges::subrange<std::reverse_iterator<I>, std::reverse_iterator<I>, K> ：

  - ranges::subrange<I, I, K>(e.end().base(), e.begin().base(), e.size()) ，若 `K` 为 `ranges::subrange_kind::sized`;
  - 否则为 ranges::subrange<I, I, K>(e.end().base(), e.begin().base()) ；

- 否则为 ranges::reverse_view{e} 。

换言之， `views::reverse` 尽可能解包逆转的视图。

`reverse_view` 始终实现 `bidirectional_range` 与 `common_range` ，而若底层视图类型 `V` 实现 `borrowed_range`、 `sized_range` 或 `random_access_range` 则它实现对应的概念。

### 表达式等价

表达式 e 表达式等价于表达式 f ，若 e 与 f 拥有相同效果，均为潜在抛出或均非潜在抛出（即 noexcept(e) == noexcept(f) ），且均为常量子表达式或均非常量子表达式。

### 数据成员

`reverse_view` 的典型实现仅保有一或二个成员对象：

- `V` 类型的底层视图（此处示为 `base_` ，名称仅用于阐释），及
- std::optional 式的缓存对象，不保有值或保有一个底层视图的尾迭代器/位置，仅若底层视图类型 `V` 不实现 `common_range` 才存在。

### 成员函数

(构造函数) (C++20) | 构造 `reverse_view` (公开成员函数)
base (C++20) | 返回底层视图 `V` (公开成员函数)
begin (C++20) | 返回 `reverse_view` 的起始迭代器 (公开成员函数)
end (C++20) | 返回 `reverse_view` 的尾迭代器 (公开成员函数)
size (C++20) | 若底层视图有界则返回其大小 (公开成员函数)
##### 继承自 std::ranges::view_interface
empty (C++20) | 返回视图是否为空。若视图满足 `forward_range` 则提供。 (`std::ranges::view_interface<D>` 的公开成员函数)
operator bool (C++20) | 返回派生视图是否为非空。若 ranges::empty 可应用于它则提供。 (`std::ranges::view_interface<D>` 的公开成员函数)
front (C++20) | 返回派生视图中的首元素。若视图满足 `forward_range` 则提供。 (`std::ranges::view_interface<D>` 的公开成员函数)
back (C++20) | 返回派生视图中的末元素。若视图满足 `bidirectional_range` 与 `common_range` 则提供。 (`std::ranges::view_interface<D>` 的公开成员函数)
operator[] (C++20) | 返回派生视图中的第 n 个元素。若视图满足 `random_access_range` 则提供。 (`std::ranges::view_interface<D>` 的公开成员函数)

## std::ranges::reverse_view::reverse_view

reverse_view() requires std::default_initializable<V> = default; | (1) | (C++20 起)
constexpr reverse_view(V r); | (2) | (C++20 起)

1) 经由其默认成员初始化器（ = V() ）值初始化 `base_` 。
2) 以 std::move(r) 初始化 `base_` 。

### 参数

r | - | 要逆转的范围

## std::ranges::reverse_view::base

constexpr V base() const& requires std::copy_constructible<V>; | (1) | (C++20 起)
constexpr V base() &&; | (2) | (C++20 起)

返回底层视图。

1) 从底层视图复制构造结果。等价于 return base_; 。
2) 从底层视图移动构造结果。等价于 return std::move(base_); 。

## std::ranges::reverse_view::begin

constexpr std::reverse_iterator<ranges::iterator_t<V>> begin(); | (1) | (C++20 起)
constexpr std::reverse_iterator<ranges::iterator_t<V>> begin() requires ranges::common_range<V>; | (2) | (C++20 起)
constexpr auto begin() const requires ranges::common_range<const V>; | (3) | (C++20 起)

1) 返回 std::make_reverse_iterator(ranges::next(ranges::begin(base_), ranges::end(base_))) 。为提供 `range` 概念所要求的的均摊常数时间复杂度，此函数在缓存对象内缓存结果，以供后继调用使用。
2-3) 等价于 return std::make_reverse_iterator(ranges::end(base_)); 。

## std::ranges::reverse_view::end

constexpr std::reverse_iterator<ranges::iterator_t<V>> end(); | (1) | (C++20 起)
constexpr auto end() const requires ranges::common_range<const V>; | (2) | (C++20 起)

等价于 return std::make_reverse_iterator(ranges::begin(base_)); 。

## std::ranges::reverse_view::size

constexpr auto size() requires ranges::sized_range<V> { return ranges::size(base_); } | (1) | (C++20 起)
constexpr auto size() const requires ranges::sized_range<const V> { return ranges::size(base_); } | (2) | (C++20 起)

若视图有界则返回其大小。

### 推导指引

template<class R> reverse_view(R&&) -> reverse_view<views::all_t<R>>; |  | (C++20 起)

### 辅助模板

template<class T> inline constexpr bool enable_borrowed_range<std::ranges::reverse_view<T>> = std::ranges::enable_borrowed_range<T>; |  | (C++20 起)

`std::ranges::enable_borrowed_range` 的此特化使得 `reverse_view` 在底层视图满足 `borrowed_range` 时满足它。

### 示例

    #include <ranges>
    #include <iostream>

    int main()
    {
        static constexpr auto il = {3, 1, 4, 1, 5, 9};

        std::ranges::reverse_view rv {il};
        for (int i : rv)
            std::cout << i << ' ';

        std::cout << '\n';

        for(int i : il | std::views::reverse)
            std::cout << i << ' ';
    }

输出：

    9 5 1 4 1 3
    9 5 1 4 1 3

### 缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

DR | 应用于 | 出版时的行为 | 正确行为
--- | --- | --- | ---
LWG 3494 | C++20 | `reverse_view` 始终不是 `borrowed_range` | 若底层视图为 `borrowed_range` 则它是

### 参阅

reverse_iterator | 逆序遍历的迭代器适配器 (类模板)
ranges::reverse (C++20) | 逆转范围中的元素顺序 (niebloid)
ranges::revserse_copy (C++20) | 创建一个范围的逆向副本 (niebloid)