c++ - 在什么情况下 ref_view{E} 格式错误而 subrange{E} 不是?
问题描述
C++20 引入了views::all
which 是一个范围适配器,它返回view
包含其范围参数的所有元素的 a。
该表达式views::all(E)
与以下表达式等效(具有相同的效果):
decay-copy(E)
如果是腐烂类型的E
模型view
。- 否则,
ref_view{E}
如果该表达式是格式良好的 - 否则,
subrange{E}
第一种情况表示 a的类型在使用(goldbotview
)管道后没有改变:views::all
auto r = views::iota(0);
static_assert(std::same_as<decltype(r), decltype(r | views::all)>);
第二种情况用于包装viewable_range
withref_view
以方便范围管道操作:
int r[] = {0, 1, 2};
static_assert(std::same_as<ranges::ref_view<int[3]>, decltype(r | views::all)>);
但是关于第三种情况,我想不出在什么情况下subrange{E}
是良构和ref_view{E}
良构。
它的目的是什么?有人可以举个例子吗?
解决方案
但是关于第三种情况,我想不出在什么情况下
subrange{E}
是良构和ref_view{E}
良构。
ref_view{E}
仅对于左值范围是格式良好的。
subrange{E}
仅适用于借用范围。你可以在[range.subrange.general]中找到它的推导指南:
template<borrowed_range R>
subrange(R&&) ->
subrange<iterator_t<R>, sentinel_t<R>,
(sized_range<R> || sized_sentinel_for<sentinel_t<R>, iterator_t<R>>)
? subrange_kind::sized : subrange_kind::unsized>;
借用范围再次是左值或选择从中借用的范围。例如,像string_view
和之类的类型span
是借用的。
因此,如果您有类似 rvalue 的东西vector<int>
,那么这不是视图(第一个项目符号),也不能从中构造 a ref_view
(因为它是右值),也不能从中构造 a subrange
(因为它是非借用范围)。
我意识到这并不能完全回答问题,因为我在输入答案时翻转了脑海中的极性。但是TC 让我满意。
另一个纯粹假设的例子是一个非视图范围,它将其内容存储在 ashared_ptr
中,然后它的迭代器也共享该数据。就像是:
struct SharedVector {
std::shared_ptr<std::vector<int>> data;
struct Iterator {
std::shared_ptr<std::vector<int>> data;
std::vector<int>::iterator cur;
// ...
};
auto begin() -> Iterator { return {data, data->begin()}; }
auto end() -> Iterator { return {data, data->end()}; }
};
右值SharedVector
不是视图(不可O(1)
破坏),你不能ref_view{E}
(因为它是右值),但这样的范围仍然可以借用,所以subrange{E}
可以工作。
推荐阅读
- php - PHP Websocket 可能根本不通过 Cloudflare?
- mysql - MySQL 5.7 - 在 JSON 中增加一个数字
- asp.net-web-api - 如何使用 Identity Server 4 (JWT) 进行基于角色的 Web API 授权
- python - 独立于控制台,python 读写多个文件
- css - WPBakery 手风琴背景颜色
- conditional - 函数的 Mathematica 条件
- python - 扫雷的网格生成
- google-maps - Places API - 拉取评论
- javascript - 织物对象构造函数不创建 cacheCanvas
- vhdl - 如何在 vhdl 中实例化具有可变大小端口的多个组件?