Visual Studio 2019版本16.10中完成C++ 20范围

我们很自豪地宣布在VS2019 V16.10版本下标准库中实现C++ 20范围的完成。 /std:c++latest . 我们 在2020年中期宣布了VS2019 v16.6中第一个有用的用户可见部分 ,涓涓细流加速流入涌出的小溪,最后的部分现在已经到位。这代表了过去两年来自多个开源贡献者的大量工作。

null

讽刺的是,范围对于标准库来说并不是什么新鲜事。STL算法总是对元素范围进行操作,其边界由表示第一个元素的迭代器和指向要进行计算的元素序列末尾的迭代器表示。C++ 20中的新奇之处在于,我们认识到直接从抽象范围传入的表达能力是抽象的,而不是传递迭代器对的——将传递迭代器作为错误的来源消除到不同的范围内,并且范围上的操作比其元素上的操作更容易编写。

C++ 20系列的设计包括哪些组件?

Relax首先通过允许表示元素序列结束的前哨符号不同于表示开始的迭代器的方式来放松旧的C++迭代器对设计。这样就可以表达简单的概念,比如由指向字符的指针和分隔符sentinel限定的范围,当指针指向字符时,分隔符sentinel与指向字符的指针进行比较 ' ' . 范围就是任何表达式 meow 以至于 std::ranges::begin(meow) std::ranges::end(meow) 返回一个迭代器和一个sentinel。

RealEngin库使用C++概念来表示类型(“这是双向迭代器”)的谓词和类型之间的关系(“这是一个有效的迭代器和前哨对吗?”)。Relax是C++标准库中新概念语言特征的第一个用途,并且是广泛使用的。概念具有很好的表达性,因为它们允许类型需求的规范,以及在较小程度上参数值的前提条件,以语法的形式直接出现在代码中,而不是以英文散文的形式出现在文档中(看到了吗 “Visual Studio 2019版本16.3中提供了C++20概念” 对于C++概念的更多讨论。

Ranges添加了一组算法——命名空间中定义的算法的镜像 std –在命名空间中 std::ranges . 这些算法受到概念的限制,并且不同于它们的同类算法 std 如果sentinel和iterator类型不同,则接受range参数和iterator sentinel对参数。

Ranges也不出所料地向标准库添加了大量Ranges。该标准将这些产品划分为不同的工厂,以创建不同的产品系列:

  • std::views::iota(0, 42) 是从0到42的整数范围,但不包括42,
  • std::views::istream_view<int>(std::cin) 是从中读取的以空格分隔的整数的范围 std::cin ,

以及将基础范围的元素转换为新范围的适配器:

  • std::views::filter(my_vec, [](const auto& x) { return x % 2 == 0; }) 是一个只有偶数元素的范围 my_vec ,
  • std::views::transform(my_vec, [](const auto& x) { return 3 * x; }) 是值为3k的元素范围,其中k是对应元素的值 my_vec .

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

auto r1 = std::views::filter(my_vec, [](const auto& x) { return x % 2 == 0; });
auto r2 = std::views::transform(r1, [](const auto& x) { return 3 * x; });

例如,要获得一个由元素组成的范围,这些元素的值是 my_vec . 该设计甚至提供了一个管道语法来促进这种组合,使用 | 要向右侧量程适配器提供左侧量程作为输入:

auto r = my_vec
       | std::views::filter([](const auto& x) { return x % 2 == 0; })
       | std::views::transform([](const auto& x) { return 3 * x; });

对算法进行等效的工作需要将中间结果和最终结果存储在某种容器中,这样的适配器组合可以一次工作一个元素来避免这种情况。

这个实现从何而来?

一个典型的STL特性描述了一个10-20页的建议,WG21将其打入一个规范,合并到C++标准中。 P0896R4“The One Ranges提案” 大约有230页。好像这还不够, 我们的范围实施跟踪问题 记录了实施范围中涵盖的22个后续建议(设计更改)和35个LWG问题(错误修复)。 我们的实施计划 从2019年5月13日开始,从STL开源之前的四个内部pr中的一个到另一个,将工作分解为bitesize片段,从“实现公共u引用和公共u类型更改”开始 99 GitHub拉取请求 结束于 2021年3月18日“Defineuu cppu libu ranges[feature test macro]” . 虽然我们确实从为Ranges技术规范创建库的原型的经验中吸取了经验,以提供指导,但STL实现几乎完全是一个完全重写,只重用一些测试用例。

这无疑是迄今为止最大的单一标准库特征,我们无法充分表达我们对C++社区中的许多成员的工作的感激,这有助于使它成为现实。我们要亲自感谢 AdamBucior公司 , 阿哈纳穆克 , 巴尔恰克 , BillyONeal公司 , bkentel公司 , 凯西卡特 , 卡贝佐尔特 , CPP学习者 , 瑞士法郎4000 , 未来 , 马哈茂德萨利赫 , 米斯科 , 姆纳苏哈拉 , 声明回复 , 斯蒂芬特拉瓦维 , 超级假发 ,和 铁姆松cpp ,每个人都提供代码、代码审阅注释或发布MSVC范围的报告。就我个人而言,我的旅程始于六年前的这个月,在堪萨斯州莱内克斯举行的WG21会议上。作为一个失业爱好者,C++迷对设计非常兴奋 Eric Niebler的N4128“标准库的范围” 我绝不会相信,我会在接下来的六年里,通过标准化过程,一直到今天的航运产品,致力于这一设计。

我今天能试试吗?

是的,这就是重点!请尝试一下可用的组件,我们会继续提供。别忘了下载(或更新) Visual Studio 2019版本16.10 ; 早期版本中提供了一些但不是所有的设计范围。请注意WG21 处理C++ 20的一些断点变化 其中三个与靶场有直接关系。您可以期望对(1)进行更改 std::ranges::split_view / std::views::split 其中,WG21自从发布C++ 20以来已经被重新设计,(2) std::ranges::join_view / std::views::join ,这已经被调整为在更多情况下可用,以及(3) std::ranges::view 概念本身将失去对默认构造的要求,允许范围适配器通过生成不可默认构造的结果视图来更有效地适应不可默认构造的基础范围。

我们很乐意听取您的反馈和建议。我们可以通过以下评论联系到您, 开发者社区 ,和Twitter( @视觉 ). 对于特定于STL或我们的Ranges实现的问题,最好的方法是 在GitHub上提交问题 .

© 版权声明
THE END
喜欢就支持一下吧,技术咨询可以联系QQ407933975
点赞0 分享