请选择 进入手机版 | 继续访问电脑版

挂宝网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 208|回复: 0

解读C++即将迎来的重大更新(一):C++20的四大新特性

[复制链接]
累计签到:62 天
连续签到:1 天

207

主题

269

帖子

7816

积分

管理员

Rank: 16

积分
7816
发表于 2020-5-18 20:40:38 | 显示全部楼层 |阅读模式
选自modernescpp
作者:JP Tech等
机器之心编译
参与:Panda、杜伟
C++20(C++ 编程语言标准 2020 版)将是 C++ 语言一次非常重大的更新,将为这门语言引入大量新特性。近日,C++ 开发者 Rainer Grimm 正通过一系列博客文章介绍 C++20 的新特性。目前这个系列文章已经更新了两篇,本篇是第一篇,主要介绍了 C++20 的 Big Four(四大新特性:概念、范围、协程和模块)以及核心语言(包括一些新的运算符和指示符)。
27ac38f1e54bd870748330a017a775ed.jpg

C++20 有很多更新,上图展示了 C++20 更新的概况。下面作者首先介绍 了 C++20 的编译器支持情况,然后介绍 The Big Four(四大新特性)以及核心语言方面的新特性。
C++20 的编译器支持
适应新特性的最简单方法是试用它们。那么接下来我们就面临着这个问题:哪些编译器支持 C++20 的哪些特性?一般来说,cppreference.com/compiler_support_能提供在核心语言和库方面的答案。
简单来说,全新的 GCC、Clang 和 EDG 编译器能提供对核心语言的最佳支持。此外,MSVC 和 Apple Clang 编译器也支持许多 C++20 特性。
83d8dbee756aec026c02ba99bfcbff47.jpg

C++20 核心语言特征。
库方面的情况类似。GCC 在库方面的支持最好,接下来是 Clang 和 MSVC 编译器。
1af763fd58d4004b1242098098061c12.jpg

C++20 库特征。
上面的截图仅展示了对应表格的前面一部分,可以看出这些编译器的表现并不是非常令人满意。即使你使用的是全新的编译器,这些编译器仍然不支持很多新特性
通常来说,你能找到尝试这些新特性的方法。下面是两个示例:
简单来说,问题没有那么严重。只需要一些调整修改,很多新特性就能进行尝试。如有必要,我会提到如何进行这样的修改。
四大新特性
概念(concept)
使用模板进行通用编程的关键思想是定义能通过各种类型(type)使用的函数和类。但是,在实例化模板时经常会出现用错类型的问题,其结果通常是几页难懂的报错信息。
现在概念来了,这个问题可以休矣。概念让你能为模板编写要求,而编译器则可以检查这个要求。概念革新了我们思考和编写通用代码的方式。原因如下:
  • 模板的要求是接口的一部分;
  • 类模板中的函数重载或特殊化可以基于概念进行;
  • 因为编译器能够比较模板参数的要求与实际的模板参数,所以能得到更好的报错信息。
但是,这还不是全部。
  • 你可以使用预定义的概念,也可以定义你自己的概念;
  • auto 和概念的用法统一到了一起。你可以不使用 auto,而是使用概念;
  • 如果一个函数声明使用了一个概念,那么它会自动变成一个函数模板。由此,编写函数模板就变得与编写函数一样简单。
下面的代码片段展示了一个简单概念 Integral 的定义和使用方式:
templateconceptboolIntegral(){returnstd::is_integral::value;}Integralautogcd(Integralautoa,Integralautob){if(b==0)returna;elsereturngcd(b,a%b);}Integral 这个概念需要 std::is_integral::value 中的类型参数 T。std::is_integral::value 这个函数来自 type-traits 库,它能在 T 为整数检查编译时间。如果 std::is_integral::value 的值为 true,则没有问题。如果不为 true,则你会收到一个编译时间报错。如果你很好奇(你也应该好奇),我的这篇文章介绍了 type-traits 库:https://www.modernescpp.com/index.php/tag/type-traits
gcd 算法是基于欧几里德算法确定最大公约数(greatest common divisor)。我使用了这个缩写函数模板句法来定义 gcd。gcd 要求其参数和返回类型支持概念 Integral。gcd 是一类对参数和返回值都有要求的函数模板。当我删除这个句法糖(syntactic sugar)时,也许你能看到 gcd 的真正本质。
下面这段代码在语义上与 gcd 算法等效:
templaterequiresIntegral()Tgcd(Ta,Tb){if(b==0)returna;elsereturngcd(b,a%b);}如果你还没看到 gcd 的真正本质,过几周我还会专门发布一篇介绍概念的文章。
范围库(Ranges Library)
范围库是概念的首个客户。它支持的算法满足以下条件:
  • 可以直接在容器上操作;无需迭代器指定一个范围;
  • 可以宽松地评估;
  • 可以组合。
简单来说:范围库支持函数模式(functional patterns)。
代码可能比语言描述更清楚。下面的函数用竖线符号展示了函数组成:
#include#include#includeintmain(){std::vectorints{0,1,2,3,4,5};autoeven=[](inti){return0==i%2;};autosquare=[](inti){returni*i;};for(inti:ints|std::view::filter(even)|std::view::transform(square)){std::cout<<i<<''; 0416}}even="" 是一个="" lambda="" 函数,其在="" i="" 为偶数时返回;lambda="" 函数="" square="" 则会将="" 映射为它的平方。其余的必须从左到右读取的第="" 个函数组成:for="" (int="" :="" ints="" |="" std::view::filter(even)="" std::view::transform(square)).="" 将过滤器="" even="" 应用于="" 的每个元素,然后将其余的每个元素映射为它们的平方。如果你熟悉函数编程,那么这读起来就像一篇散文诗。
协程(Coroutines)
协程是广义的函数,能在保持状态的同时暂停或继续。协程通常用来编写事件驱动型应用。事件驱动型应用可以是模拟、游戏、服务器、用户接口或算法。协程也通常被用于协作式多任务(cooperative multitasking)。
我们这里不介绍 C++20 的具体协程,而会介绍编写协程的框架。编写协程的框架由 20 多个函数构成,其中一部分需要你去实现,另一部分则可能需要重写。因此,你可以根据需求调整协程。
下面展示了一个特定协程的用法。下面的程序使用了一个能产生无限数据流的生成器:
GeneratorgetNext(intstart=0,intstep=1){autovalue=start;for(inti=0;;++i){co_yieldvalue;//1value+=step;}}intmain(){std::cout<<std::endl;std::cout<<"getnext():";autogen=getnext();for(inti=0;i<=10;++i){gen.next(); 2std::cout<<""<<gen.getvalue();}std::cout<<"="" ";std::cout<<"getnext(100,-10):";autogen2="getNext(100,-10);for(inti=0;i<=20;++i){gen2.next();//3std::cout<<""<<gen2.getValue();}std::cout<<std::endl;}必须补充几句。这段代码只是一个代码段。函数" getnext="" 是一个协程,因为它使用了关键字="" co_yield。getnext="" 有一个无限的循环,其会在="" co_yield="" 之后返回="" value。调用="" next()(注释的="" 第="" 2、3="" 行)会继续这个协程,接下来的="" getvalue="" 调用会获取这个值。在="" 调用之后,这个协程再一次暂停。其暂停会一直持续到下一次调用="" next()。我的这个示例中有一个很大的未知,即="" 函数的返回值="" generator。这部分内容很复杂,后面我在写协程的文章中更详细地介绍。
使用 Wandbox 在线编译器,我可以向你展示这个程序的输出:
2a0947cbb7b3259a1e445cfeabf80390.jpg


模块(Module)
模块部分简单介绍一下就好。模块承诺能够实现:
  • 更快的编译时间;
  • 宏的隔离;
  • 表达代码的逻辑结构;
  • 不必再使用头文件(header file);
  • 摆脱丑陋的宏方法。

原文链接:https://www.modernescpp.com/index.php/thebigfour

</std::endl;std::cout<<"getnext():";autogen=getnext();for(inti=0;i</i<
1b5ca1b55bacd78f52a44ae5ac1f609f.jpg
78f1ecda9ac7e170ab535b6784facf8d.jpg
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋| 挂宝网  |网站地图

挂宝网 辅助论坛 X3.4© 2019-2020 GuaB.Net

快速回复 返回顶部 返回列表