- ranges[meta header]
- concept[meta id-type]
- std::ranges[meta namespace]
- cpp20[meta cpp]
namespace std::ranges {
template<class T>
concept view = range<T> && movable<T> && enable_view<T>;
}
- range[link range.md]
- movable[link /reference/concepts/movable.md]
- enable_view[link enable_view.md]
view
は、ビューを表すコンセプトである。view
の要件は意味論要件がメインなので、enable_view
を特殊化して有効にしない限りview
とはならない。
view
の例:
- イテレータペアをラップするRange
- 要素を
shared_ptr
で持っていて、Rangeのコピーをすると要素の所有権を共有するようなRange - 要素を必要に応じて生成するRange
型T
がview
のモデルとなるのは、以下の条件をすべて満たす場合である。
T
のムーブコンストラクタがO(1)T
のムーブ代入は、T
のデストラクタとムーブコンストラクタを連続で実行する場合より複雑にならない- M 個の要素を持つ
T
型のオブジェクトから N 個のT
型オブジェクトをムーブやコピーで作ったとき、それら N 個のT
型オブジェクトは O(N + M) で破棄できる copy_constructible
<T>
がfalse
、またはT
のコピーコンストラクタがO(1)copyable
<T>
がfalse
、またはT
のコピー代入はT
のデストラクタとコピーコンストラクタを連続で実行する場合より複雑にならない
view
とborrowed_range
には直接の包含関係はないが、要素を所有していると一般にこれらの要件は満たせないため、borrowed_range
でもある場合が多い。
view
を自作する場合、view_interface
を基底クラスにすると便利である。
#include <ranges>
#include <string_view>
#include <span>
#include <vector>
int main()
{
// vectorはviewではない
static_assert(!std::ranges::view<std::vector<int>>);
// string_viewはview
static_assert(std::ranges::view<std::string_view>);
// spanはview
static_assert(std::ranges::view<std::span<int>>);
}
- std::ranges::view[color ff0000]
- std::span[link /reference/span/span.md]
- C++20
- Clang: 13.0.0 [mark verified]
- GCC: 10.1.0 [mark verified]
- ICC: ??
- Visual C++: 2019 Update 10 [mark verified]
- N4861 24 Ranges library
- C++20 ranges
- P2325R3 Views should not be required to be default constructible (本提案文書はC++20に遡って適用されている)
- P2415R2 What is a
view
? (本提案文書はC++20に遡って適用されている)