c++20新特性
大特性
协程
这个协程有点像python的。有迭代器,比较适合异步编程,有空写一篇新协程的文章。
模块
c++史诗级地加强,但是STL自己都不支持。还是任重道远。
约束与概念
模板高阶技巧进一步加深。更加复杂了,可以实现更加复杂的功能。有空写文章。
小特性
功能特性测试
加了一些用于测试(编译器?环境?)是否具备某种功能的宏。
三目比较符<=>
和减法的机制比较类似。
表达式返回一个对象,使得
- 若 左操作数
<
右操作数 则(a <=> b) < 0
- 若 左操作数
>
右操作数 则(a <=> b) > 0
- 而若 左操作数 和 右操作数 相等/等价则
(a <=> b) == 0
。
和减法的区别在于
- 语法级避免溢出等问题(避免了很多非良构的情况)
- 由于不需要返回具体的差值,所以可以采用更为优秀的实现方式
- 看上去更加直观,一致性更好(更优美?)
范围for可以使用初始化语句
字面意思。不知道为什么不和if
、switch
一起在c++17推出。
新增了一些属性
[[no_unique_address]]
,这个是用来节约struct
空间的。[[likely]]
,switch
、case
里面用来指示优先判断的。和if else链条里面把使用效率高的放在前面一个原理。
lambda
初始化捕获中的包展开
参数包的优化。
移除了在多种上下文语境中,使用 typename
关键字以消除类型歧义的要求
没具体讲是哪里,不过c++歧义性常有的事。碰到再看。
consteval
说明符
说明函数必须生成编译器常量,一般用来配合constexpr
。
consteval int sqr(int n) {
return n*n;
}
constexpr int r = sqr(100); // OK
constinit 说明符
声明拥有静态或线程存储期的变量,换句话说就是初始化的时候,用来初始化的东西是静态的。不知道用处是什么,回头用到了再说。
const char *g() { return "dynamic initialization"; }
constexpr const char *f(bool p) { return p ? "constant initializer" : g(); }
constinit const char *c = f(true); // OK
// constinit const char *d = f(false); // 错误
更为宽松的 constexpr
要求
用到再说,反正不是严格了就没事。
规定有符号整数以补码实现
以前也是这样的,现在给编译器提出具体的要求了。
聚合初始化优化
初始化又优化了,新增了以下三条语法。
T object = { .指派符 = arg1 , .指派符 { arg2 } ... };
T object { .指派符 = arg1 , .指派符 { arg2 } ... };
T object (arg1, arg2, ...);
前两者如下使用
struct A { int x, y; };
struct B { struct A a; };
struct A a = {.y = 1, .x = 2}; // 合法 C,非法 C++(乱序)
int arr[3] = {[1] = 5}; // 合法 C,非法 C++(数组)
struct B b = {.a.x = 0}; // 合法 C,非法 C++(嵌套)
struct A a = {.x = 1, 2}; // 合法 C,非法 C++(混合)
第三个用法原来是没有的。圆括号的初始化只能用于类的初始化语法,不能用于结构体的,现在可以了。相当于给结构体了一个默认的构造函数
new数组特性改了
在常量表达式求值期间,始终省略对分配函数的调用。只有在其他情况下调用可替换全局分配函数的 new
表达式能在常量表达式中求值。
编译器不会调用new
,除非有常量。这个特性不让我震惊,震惊的是原来new
竟然支持编译期运行。。。。。
License:
CC BY 4.0