文章

c++20新特性

大特性

协程

这个协程有点像python的。有迭代器,比较适合异步编程,有空写一篇新协程的文章。

模块

c++史诗级地加强,但是STL自己都不支持。还是任重道远。

约束与概念

模板高阶技巧进一步加深。更加复杂了,可以实现更加复杂的功能。有空写文章。

小特性

功能特性测试

加了一些用于测试(编译器?环境?)是否具备某种功能的宏。

三目比较符<=>

和减法的机制比较类似。

表达式返回一个对象,使得

  • 若 左操作数 < 右操作数 则 (a <=> b) < 0
  • 若 左操作数 > 右操作数 则 (a <=> b) > 0
  • 而若 左操作数 和 右操作数 相等/等价则 (a <=> b) == 0

和减法的区别在于

  • 语法级避免溢出等问题(避免了很多非良构的情况)
  • 由于不需要返回具体的差值,所以可以采用更为优秀的实现方式
  • 看上去更加直观,一致性更好(更优美?)

范围for可以使用初始化语句

字面意思。不知道为什么不和ifswitch一起在c++17推出。

新增了一些属性

  • [[no_unique_address]],这个是用来节约struct空间的。
  • [[likely]]switchcase里面用来指示优先判断的。和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