所在的位置: C++ >> C++优势 >> C20Ranges在VS2019v1

C20Ranges在VS2019v1

今天我们很高兴地宣布,我们在VSv16.10中完成了标准库中的C++20Ranges特性。在去年(年)年中的时候,我们官宣了在VSv16.6中的第一个可用且用户可见的Ranges部分,涓涓细流加速成一股涌流,最终部分现已就位。这代表了过去两年开源贡献者的大量工作。

具有讽刺意味的是,Ranges对于标准库来说并不是什么新鲜事。STL算法总是对元素范围进行操作,这些元素的边界由表示第一个元素的迭代器和指向经过计算的元素序列末尾的迭代器表示。C++20Ranges的新颖之处在于,我们认识到直接作为抽象传递Ranges而不是传递迭代器对所带来的表达能力——消除了将迭代器传递到不同Ranges作为错误来源——并且对Ranges的操作可以组合更多,相比于对其元素的操作来说,这样更加容易。

哪些组件构成了C++20Ranges设计?

Ranges首先放宽了旧的C++迭代器的设计,允许表示元素序列末尾的标记与表示开始的迭代器具有不同的类型。这可以用来表达简单的概念,例如由指向字符的指针和分隔符标记界定的范围,当指针指向‘\0’时,该分隔符与指向字符的指针相等。一个Range是任何表达式meow使得std::ranges::begin(meow)和std::ranges::end(meow)返回一个迭代器和一个哨兵(sentinel)。

Ranges库使用C++概念表达了对类型的谓词(“这是一个双向迭代器吗?”)和类型之间的关系(“这是一个有效的迭代器和哨兵对吗?”)。Ranges是C++标准库中新的概念语言特性的第一次使用——而且是相当广泛的使用。概念具有很好的表现力,因为它们允许类型要求的规范,以及在较小程度上对参数值的先决条件,直接作为语法出现在代码中,而不是作为英文散文出现在文档中。(有关C++概念的更多讨论,请参阅“VisualStudio版本16.3中的C++20概念”。)

Ranges在命名空间std::ranges中添加了一组算法——命名空间std中定义的算法的镜像。这些算法受概念约束,与std中的同级不同,它们接受范围参数和迭代器-哨兵对参数,其中哨兵和迭代器类型不同。

Ranges也毫不奇怪地向标准库添加了一系列范围。标准将这些拆分为创建范围的工厂:std::views::iota(0,42)是从0到但不包括42的整数范围,std::views::istream_view(std::cin)是从std::cin读取的以空格分隔的整数范围

将基础范围的元素转换为新范围的适配器:std::views::filter(my_vec,[](constautox){returnx%2==0;})是仅包含my_vec偶数元素的范围,std::views::transform(my_vec,[](constautox){return3*x;})是值3k的元素范围,其中k是my_vec的对应元素的值。

范围适配器通常最好被认为是惰性的、可组合的算法,因为它们在你开始迭代它们之前不起作用,并且它们是从范围到范围的函数。我们可以将上面两个例子组合成:

例如,要获取由值是my_vec偶数元素值的三倍的元素组成的范围。该设计甚至提供了一种管道语法来促进这种组合,使用

提供左侧范围作为右侧范围适配器的输入:

使用算法做等效的工作需要将中间和最终结果存储在某种容器中,像这样的适配器组合通过一次工作元素来避免这种情况。

这个实现从哪里来?

一个10~20页的提案描述了一个典型的STL特性,WG21将其完善为规范以合并到C++标准中。PR4“单一范围提案”大约有页。似乎这还不够,我们对Ranges实施的跟踪问题记录了Ranges实施中涵盖的22个后续提案(设计更改)和35个LWG问题(错误修复)。我们的实施计划从年5月13日开始的“实施


转载请注明:http://www.aierlanlan.com/grrz/4813.html