我们将能够使用C ++ 20构建具有视图的容器吗?


10

C ++ 20标准版本将范围引入C ++。

我的问题:我们能否构造(现有)任何范围的标准库容器?更重要的是,具有范围视图吗?

例如,这将:

#include <vector>
#include <iostream>
#include <ranges>

int main() {
    auto sq = [](int x) { return x * x; };
    std::vector<int> vec { 3, 4, 5 };
    std::vector<int> squares { std::ranges::views::transform(vec, sq) };
    for(auto i : squares) { std::cout << i << ' '; }
    std::cout << std::endl;
}

是可以打印的有效程序9 16 25吗?

可以使用ranges-v3库进行编译,这是值得的。



每个StoryTeller:明显重复以下内容:为什么即将发布的Ranges库不支持某个范围内的容器初始化?-但请注意,投票解决可能仍会改变答案!
戴维斯·鲱鱼

@DavisHerring有什么可以改变的?最初没有考虑使用P1206,而且我认为这里没有任何未注释的注释吗?P1391是采用范围的构造函数(尽管有误导的例子)。
巴里

@Barry:LEWG 如此在科纳转发了它,但我想我误解了最近关于它的反射器流量。
戴维斯·鲱鱼

@DavisHerring哦,我错过了讨论两次的机会 -我向下滚动到4-7调查,并认为是那样。
巴里

Answers:


8

我的问题:我们能否构造(现有)任何范围的标准库容器?更重要的是,具有范围视图吗?

否。可以在满足正确条件的任意范围内构造的唯一标准库组件是std::span<T>

标准库可能会遵循的方向是range-v3的方向(请注意range-v3的链接示例确实可以编译,但警告过时的转换)-使用帮助程序为您完成转换:

std::vector<int> squares =
    std::ranges::views::transform(vec, sq) | std::ranges::to<std::vector>;

不使用范围构造器的原因之一可以从您正在使用的示例中看出:

std::vector<int> squares { std::ranges::views::transform(vec, sq) };

考虑一下该声明与这两个声明有何不同:

std::vector v { std::ranges::views::transform(vec, sq) };
std::vector w ( std::ranges::views::transform(vec, sq) );

v必定是一个vector<transform_view<...>>包含单个的transform_view,而w必定是一个vector<int>

而且,向标准库中添加更多的,经过严格约束的容器构造函数无论如何都无法帮助第三方容器类型,而类似的工具ranges::to在所有情况下都可以很好地工作。


这些语句已初始化vw在我看来也一样。也许您打算声明wvector<int>。否则,这是正确的答案。
埃里克·尼布尔

5
@EricNiebler准确:-)它们看起来确实一样。他们不一样。
巴里

因此,我的程序可以编译,但不会执行我认为的操作。好。
einpoklum

1
谢谢,CTAD ...
TC

您能解释一下为什么vw不同吗?它与构造函数模板参数推导的工作方式有关吗?
Johannes Schaub-litb
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.