# std::ranges::view_interface

< cpp‎ | ranges

定义于头文件 `<ranges>` |  |
template<class D> requires std::is_class_v<D> && std::same_as<D, std::remove_cv_t<D>> class view_interface; |  | (C++20 起)

`std::ranges::view_interface` 是用于定义范围接口的辅助类模板。

`view_interface` 常以 CRTP 使用：

    class my_view : public std::ranges::view_interface<my_view> {
    public:
        auto begin() const { /*...*/ }
        auto end() const { /*...*/ }
        // 若 begin() 返回向前迭代器且 end() 返回其哨位则提供 empty() 。
    };

### 成员函数

empty (C++20) | 返回视图是否为空。若视图满足 `forward_range` 则提供。 (公开成员函数)
operator bool (C++20) | 返回派生视图是否为非空。若 ranges::empty 可应用于它则提供。 (公开成员函数)
data (C++20) | 返回派生视图的数据的地址。若视图的迭代器类型满足 `contiguous_iterator` 则提供。 (公开成员函数)
size (C++20) | 返回派生视图中的元素数。若视图满足 `forward_range` 且其哨位与迭代器类型满足 `sized_sentinel_for` 则提供。 (公开成员函数)
front (C++20) | 返回派生视图中的首元素。若视图满足 `forward_range` 则提供。 (公开成员函数)
back (C++20) | 返回派生视图中的末元素。若视图满足 `bidirectional_range` 与 `common_range` 则提供。 (公开成员函数)
operator[] (C++20) | 返回派生视图中的第 n 个元素。若视图满足 `random_access_range` 则提供。 (公开成员函数)

### 示例

    #include <ranges>
    #include <vector>
    #include <iostream>

    template <class T, class A>
    class VectorView : public std::ranges::view_interface<VectorView<T, A>> {
    public:
        VectorView() = default;
        VectorView(const std::vector<T, A>& vec) :
            m_begin(vec.cbegin()), m_end(vec.cend()) {}
        auto begin() const { return m_begin; }
        auto end() const { return m_end; }
    private:
        typename std::vector<T, A>::const_iterator m_begin{}, m_end{};
    };

    int main()
    {
        std::vector<int> v = {1, 4, 9, 16};

        VectorView view_over_v{v};

        // 我们能以 begin() 与 end() 迭代。
        for (int n : view_over_v) {
            std::cout << n << ' ';
        }
        std::cout << '\n';

        // 我们能在继承 view_interface 时免费地获得 operator[]
        // 因为我们满足 random_access_range 概念。
        for (std::ptrdiff_t i = 0; i < view_over_v.size(); i++) {
            std::cout << "v[" << i << "] = " << view_over_v[i] << '\n';
        }
    }

输出：

    1 4 9 16
    v[0] = 1
    v[1] = 4
    v[2] = 9
    v[3] = 16

### 缺陷报告

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

DR | 应用于 | 出版时的行为 | 正确行为
--- | --- | --- | ---
LWG 3549 | C++20 | 要求 `view_interface` 派生自 `view_base` ，这有时要求视图中的多个 `view_base` 子对象 | 移除继承

### 参阅

ranges::subrange (C++20) | 将迭代器/哨位对结合为一个 `view` (类模板)