近日,C++20标准正式公布,这不禁让人想起了年年底C++标准委员会讨论C++20新特性的光景。
当时“C++20还未发布,就已凉凉?”的论调可谓火热,其中C++模块化更是引起了国内外开发者的嫌弃:C++开发者怒了:这个无用的模块设计最终会害死C++!
这个未出世就被群嘲“劝退”的C++20,如今终于正式发布,那它带来了哪些新特性呢?一起来看大佬实战探究总结!
作者
连少华责编
张文
头图
CSDN下载自视觉中国
近日,ISOC++委员会正式发布了C++20标准,命名为ISO/IEC:。
作为程序员,看到新标准发布总想尝鲜,目前gcc10.2可以支持部分C++20标准,编译的时候需要使用编译选项:-std=c++2a。
Constraintsandconcepts(约束和概念)
在类模板和函数模板编程中,主要用于对模板参数的结束和限制,这种约束和限制发生在编译期,编译错误不再那么晦涩难懂了。在模板编程中,可以限制模板参数的类型或具用某种特性,如:可以限制为整型、数值型、bool型、或必须支持hash特性、或某个类的派生类型等。
在C++20中Concepts是非常重要的概念,模板编程终于有了质的提升。
Concepts
Concepts是requirements的具名集合,concepts需要声明在命名空间中,语法如下:
templatetemplate-parameter-listconceptconcept-name=constraint-expression;
如下所示:
templatetypenameTconceptHashable=requires(Ta){{std::hashT{}(a)}-std::convertible_tostd::size_t;};//声明了一个名为Hashable的conceptstructmeow{};templateHashableTvoidf(T);//约束这个T必须满足Hashableconcept,否则无法编译通过。intmain(){f(abcs);//OK,string是可hash的f(meow{});//Error:meow结构体不是可hash的,当然可以让其支持hash。}//templatetypenameTconceptC=sizeof(T)10;templateCTclasstest{};templateCTvoidfunc(Tt);
Constraints
约束是逻辑操作和操作数的序列,它用于指定对模板实参的要求。可在requires表达式中出现,也可直接作为concept的主体。
有三种类型的约束:
合取(conjunction)析取(disjunction)原子约束(atomicconstraint)如下所示:
templateIncrementableTvoidf(T)requiresDecrementableT;templateIncrementableTvoidf(T)requiresDecrementableT;//OK:重声明
Requires
requires用于约束模板参数或具体的参数。
requires子句
如下所示:
templatetypenameTvoidf(T)requiresEqT;//可作为函数声明符的最末元素出现templatetypenameTrequiresAddableT//或在模板形参列表的右边Tadd(Ta,Tb){returna+b;}
关键词requires必须后随某个常量表达式(故可以写为requirestrue),但其意图是使用某个具名概念(如上例),或具名概念的一条合取/析取,或一个requires表达式。
表达式必须具有下列形式之一:
初等表达式,例如Swappable、std::is_integral::value、(std::is_object_v…)或任何带括号表达式以运算符连接的初等表达式的序列以运算符
连接的前述表达式的序列requires表达式
语法如下:
requires{requirement-seq}requires(parameter-list(optional)){requirement-seq}
parameter-list-与函数声明中类似的形参的逗号分隔列表,但不允许默认实参且不能以(并非指定包展开的)省略号结尾。这些形参无存储期、连接或生存期,它们仅用于辅助进行各个要求的制定。这些形参在要求序列的闭}前处于作用域中。requirement-seq-要求(requirement)的序列,描述于下(每个要求以分号结尾)。
requirement-seq中的每个要求必须是下面的四项之一:
简单要求(simplerequirement)类型要求(typerequirement)复合要求(