namespace std::ranges {
template<class T>
concept borrowed_range = range<T> && (is_lvalue_reference_v<T> || enable_borrowed_range<remove_cvref_t<T>>);
}
概要
borrowed_range
は、Rangeを所有しないrange
を表すコンセプトである。Rangeオブジェクトの左辺値参照はborrowed_range
である。
左辺値参照以外の型が値を所有するか否かは構文要件で定義できないため、変数テンプレートenable_borrowed_range
を特殊化してtrue
となるようにすることでborrowed_range
を満たすようにする。
モデル
decltype((t))
がT
であるような式t
があるとする。T
がborrowed_range
のモデルとなるのは、t
が示すオブジェクトの寿命とそこから取得したイテレータの有効性が結びついていない場合である。
備考
borrowed_range
なRangeはそのイテレータの有効性がRangeの寿命と結びついていないため、そのようなRangeを値で受け取ってイテレータを値で返すような関数がダングリングイテレータの心配なく利用できる。
例
#include <ranges>
#include <string_view>
#include <span>
#include <vector>
int main()
{
// vectorは要素を所有しているので、borrowed_rangeではない
static_assert(!std::ranges::borrowed_range<std::vector<int>>);
// vectorの参照は要素を所有していないので、borrowed_rangeである
static_assert(std::ranges::borrowed_range<std::vector<int>&>);
// string_viewは文字列を所有していないので、borrowed_rangeである
static_assert(std::ranges::borrowed_range<std::string_view>);
// spanはintを所有していないので、borrowed_rangeである
static_assert(std::ranges::borrowed_range<std::span<int>>);
}
出力
バージョン
言語
- C++20
処理系
- Clang: 13.0.0 ✅
- GCC: 10.1.0 ✅
- ICC: ??
- Visual C++: 2019 Update 10 ✅