首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么C++23范围::不限制容器类型C为范围?

为什么C++23范围::不限制容器类型C为范围?
EN

Stack Overflow用户
提问于 2022-09-19 04:06:51
回答 1查看 197关注 0票数 4

C++23引入了非常强大的ranges::to,用于从范围内构造对象(通常是容器),定义如下([range.utility.conv.to]):

代码语言:javascript
复制
template<class C, input_­range R, class... Args> requires (!view<C>)
  constexpr C to(R&& r, Args&&... args);

请注意,它只将模板参数C限制为不属于view,也就是说,C甚至可能不是range

但是,它的实现使用range_value_t<C>获取C的元素类型,这使得C至少成为一个range,因为模板参数R必须对range建模这一range_value_t约束。

那么,为什么ranges::to对模板参数C的约束如此松散呢?

我注意到论文的R3版本以前将C约束为input_range,这显然是合理的,因为input_range保证range_value_t格式良好,但是在R4中,这个约束被删除了。我没有找到任何关于这一变化的评论。

因此,删除C必须是input_range的约束需要考虑哪些事项?

是否有一个实际的例子来说明这种约束放松的好处?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-19 16:12:46

这是一个与我们需要解决的措辞问题,我将在今天晚些时候开始一个问题。我是LWG 3785

那么,删除C必须是input_range的约束需要考虑什么呢?

ranges::to的目标是收集一个范围.某物。但它不必是一个实际的范围。只是消耗了所有元素的东西。当然,最常见的用法是实际的容器类型,而最常见的实际容器类型将是std::vector

还有其他有趣的用例,但实际上没有太多的理由拒绝。

假设我们有一个范围的std::expected<int, std::exception_ptr>,称为results。也许我们做了一些计算,也许有些计算失败了。我可以把它收集到一个std::vector<std::expected<int, std::exception_ptr>>中,这可能很有用。但是还有另一种选择:我可以把它收集到一个std::expected<std::vector<int>, std::exception_ptr>中。也就是说,如果所有的计算都成功了,我将得到所有结果的值类型。但是,如果其中任何一个失败了,我将得到第一个错误。这是一件非常有用的事情,这在概念上非常符合ranges::to对其输入所做的事情--所以这可以支持:

代码语言:javascript
复制
auto processed = results | ranges::to<std::expected>();
if (not processed) {
    std::rethrow_exception(processed.error());
}

std::vector<int> values = std::move(processed).value();
// go do more stuff

这对于支持是非常有用的--特别是因为不支持它并不需要付出任何代价。我们只是不能过早地拒绝它。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73768399

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档