std::ranges::view, std::ranges::enable_view, std::ranges::view_base
來自 cppreference.com
定義於標頭檔案 <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 起) |
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,為不建模的型別特化為 false。此類特化必須 在常量表達式中可用,並且型別為 const bool。目錄 |
[編輯] 語義要求
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
型別的例子有
- 包裝一對迭代器的
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 | 析構時間複雜度的限制過於嚴格 | 已放寬 |