std::ranges:: view, std::ranges:: enable_view, std::ranges:: view_base
|
定义于头文件
<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
=
|
(2) | (C++20 起) |
|
struct
view_base
{
}
;
|
(3) | (C++20 起) |
enable_view
变量模板用于指示某个
range
是否为
view
。
/*is-derived-from-view-interface*/
<
T
>
为
true
当且仅当
T
有且仅有一个公有基类
ranges::
view_interface
<
U
>
(其中
U
为某类型),且
T
没有其他类型的
ranges::
view_interface
<
V
>
基类。
用户可对满足
view
概念的 cv 未限定程序定义类型特化
enable_view
为
true
,对不满足的类型特化为
false
。此类特化必须
可用于常量表达式
,且类型为
const
bool
。
目录 |
语义要求
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
类型的示例包括:
-
一种包装迭代器对的
range类型,例如 std :: ranges:: subrange < I > 。 -
一种通过
std::shared_ptr
持有元素并与所有副本共享所有权的
range类型。 -
一种按需生成其元素的
range类型,例如 std::ranges::iota_view 。
像
std::
vector
<
std::
string
>
这样的可复制容器通常不满足
view
的语义要求,因为复制容器会复制所有元素,这无法在常数时间内完成。
虽然视图最初被描述为可廉价复制且非拥有的范围,但一个类型并不需要是可复制或非拥有的才能满足
view
概念。然而,它仍然必须满足廉价复制(若可复制)、移动、赋值和销毁的要求,以确保
范围适配器
不会出现预期之外的复杂度。
默认情况下,若某个类型同时满足
movable
与
range
概念,且满足以下条件之一,则被视为视图:公开明确地继承自
view_base
,或精确继承自
std::ranges::view_interface
的某一个特化。
示例
最小视图。
#include <ranges> struct ArchetypalView : std::ranges::view_interface<ArchetypalView> { int* begin(); int* end(); }; static_assert(std::ranges::view<ArchetypalView>);
缺陷报告
下列行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。
| 缺陷报告 | 适用标准 | 发布时行为 | 正确行为 |
|---|---|---|---|
| P2325R3 | C++20 |
view
要求
default_initializable
|
不再要求 |
| LWG 3549 | C++20 |
enable_view
未检测从
view_interface
的继承
|
能够检测 |
| P2415R2 | C++20 | 对析构时间复杂度限制过于严格 | 已放宽 |