命名空间
变体
视图
操作

std::ranges::view, std::ranges::enable_view, std::ranges::view_base

来自 cppreference.cn
< cpp‎ | ranges
 
 
范围库
范围适配器
 
定义于头文件 <ranges>
template<class T>
concept view = ranges::range<T> && std::movable<T> && ranges::enable_view<T>;
(1) (自 C++20 起)
template<class T>

constexpr bool enable_view =

    std::derived_from<T, view_base> || /*is-derived-from-view-interface*/<T>;
(2) (自 C++20 起)
struct view_base { };
(3) (自 C++20 起)
1) view 概念指定了 range 类型的要求,该类型具有适用于构建范围适配器管道的语义属性。
2) enable_view 变量模板用于指示 range 是否为 view/*is-derived-from-view-interface*/<T> 当且仅当 T 恰好有一个公共基类 ranges::view_interface<U> (对于某些类型 U)时,且 T 没有类型为 ranges::view_interface<V> 的基类(对于任何其他类型 V)时,为 true
用户可以为建模 view 的 cv 限定的程序定义类型将 enable_view 特化为 true,并为不建模 view 的类型特化为 false。此类特化必须是 可在常量表达式中使用的,并且具有类型 const bool
3)view_base 派生使 range 类型能够建模 view

目录

[编辑] 语义要求

1) T 建模 view 仅当
  • T 的移动构造具有常数时间复杂度,且
  • 如果从持有 M 个元素的 T 对象复制和/或移动了 N 个副本,则这些 N 个对象的销毁具有 𝓞(N+M) 的复杂度(这意味着已移动源 view 对象的销毁具有 𝓞(1) 的复杂度),且
  • 要么 std::copy_constructible<T>false,要么 T 的复制构造具有常数时间复杂度,且
  • 要么 std::copyable<T>false,要么 T 的复制赋值的时间复杂度不高于销毁后跟复制构造。

[编辑] 特化

对于以下标准模板的所有特化,enable_view 的特化定义为 true

(自 C++26 起)

[编辑] 注释

view 类型的示例包括:

诸如 std::vector<std::string> 之类的可复制容器通常不符合 view 的语义要求,因为复制容器会复制所有元素,而这不能在常数时间内完成。

虽然视图最初被描述为廉价可复制且非拥有的范围,但类型不一定需要是可复制的或非拥有的才能建模 view。但是,它仍然必须是廉价复制(如果可复制)、移动、赋值和销毁的,以便 范围适配器 不会具有意外的复杂度。

默认情况下,如果类型公开且明确地派生自 view_base,或者恰好是一个 std::ranges::view_interface 的特化,则建模 movablerange 的类型被认为是视图。

[编辑] 示例

最小视图。

#include <ranges>
 
struct ArchetypalView : std::ranges::view_interface<ArchetypalView>
{
    int* begin();
    int* end();
};
 
static_assert(std::ranges::view<ArchetypalView>);

[编辑] 缺陷报告

以下行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。

DR 应用于 已发布行为 正确行为
P2325R3 C++20 view 要求 default_initializable 不要求
LWG 3549 C++20 enable_view 未检测到从 view_interface 的继承 检测到
P2415R2 C++20 对销毁的时间复杂度的限制过于严格 已放宽