namespace std::ranges {
template<class T>
concept view = range<T> && movable<T> && enable_view<T>;
}
概要
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>>);
}
17
#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>>);
}
出力
バージョン
言語
- C++20
処理系
- Clang: 13.0.0 ✅
- GCC: 10.1.0 ✅
- ICC: ??
- Visual C++: 2019 Update 10 ✅
参照
- 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に遡って適用されている)