C++ 20 & C++ 23 部分新功能

· · 科技·工程

收录不全面,为日常给 OIer 在 洛谷(支持 C++20 但不支持 C++ 23/Hydro(支持 C++ 20 & 23)等做题用。

C++ 20

从 GCC 8 开始支持,未完全支持。

三路比较运算符(<=>

是一种运算符(废话)。

但他返回的不是 bool,而是 std::strong_orderingstd::partial_ordering

如果操作数之一是 bool 类型而另一个不是,那么程序非良构。

如果需要进行除了从整数类型到浮点数类型之外的窄化转换,那么程序非良构。

范围 for 中的初始化语句和初始化器

开始支持 init-statement,可以在 for 循环的初始化部分声明变量。

人话:范围 for 循环语句支持初始化语句。

示例:

for(int i = 0; pair<int, int> j : Map)

日历功能

格式化库 (std::format)

头文件 <format>

示例:

std::string s = std::format("Hello, world!\n");
// == "Hello, world!\n"
std::string s = std::format("The answer is {}.", 42); 
// == "The answer is 42."
std::string s = std::format("I'd rather be {1} than {0}.", "right", "happy"); 
// == "I'd rather be happy than right."
std::vector<int> v = {1, 2, 3}; 
std::string s = fmt::print("{}\n", v); 
// == "[1, 2, 3]"

数学常数

_Tp 填入数据类型(如 double):

函数

C++ 23

if consteval

指在编译阶段可以可以进行条件编译,并根据结果选择可以编译或者不编译哪些代码块。

if consteval {} else {}
if !consteval {} else {}

多维下标运算符

大白话:重载数组下标。

struct Matrix4f {
    float m[4][4];
    float * const operator [] (const int i) { return m[i]; }
};

标记不可达代码 (std::unreachable)

标记程序中不可达的代码部分,帮助编译器进行更激进的优化。通过明确标记不可达的代码,编译器可以进行更有效的优化和错误检查,减少不必要的警告或误报。

exit(0) 不同,exit(0) 是程序运行时推出但仍需编译,而 std::unreachable(); 是编译都不编译了。

平台无关的假设 ([[assume]])

[[assume]] 属性允许开发者在代码中声明某些条件总是为真,帮助编译器进行更好的优化。

int divide(int a, int b)
{
    [[assume(b != 0)]];
    return a / b;
}

命名通用字符转义

'\N{WHITE SMILING FACE}' WHITE SMILING FACE 是 Unicode 字符的名字,对应的 Unicode 码点是 U+263A。

新容器:flat_mapflat_set

真正有用的东西来了!

性能优化的平面映射 (flat_map) 和集合 (flat_set) 容器。

使用连续的内存块存储元素,从而减少了内存分配和访问时间。

适合于频繁查找操作的场景。

运行时堆栈跟踪

头文件 <stacktrace>

std::stacktrace::current()

示例输出:

foo() at example.cpp:5
main() at example.cpp:10

printprintln

类似于 format()(C++ 20)。

printlnprint 多了一个换行符。