🍌 C++23 特性

C++23 更偏向实用增强 + 库补全,在不大改语法的前提下,让现代 C++ 更好用。

if consteval

区分是否在编译期求值:

constexpr int f(int x) {
    if consteval {
        return x * 2;   // 编译期路径
    } else {
        return x * 3;   // 运行期路径
    }
}

int main()
{
    constexpr int a = 1;
    constexpr int res = f(a);
    std::cout << res << std::endl; // 2
    int b = rand() / 100;
    std::cout << b << " " << f(b) <<std::endl; // 18042893 54128679
    return 0;
}

对 constexpr、元编程很有用。

显式this参数(Deducing this)

成员函数可像普通函数一样写

struct S {
    int x;
    auto get(this S const& self) {
        return self.x;
    }
};

编写通用成员函数、完美转发更自然。

多参数下标运算

struct M {
    int operator[](int i, int j) const { return i + j; }
};

M m;
auto v = m[1, 2];

写矩阵、网格类型更直观。

static operator()

auto l = [] static { return 42; };

便于 constexpr 与无状态调用。

说的是 C++23 引入的“static lambda” 特性。 本质是:让 lambda 的 operator() 变成 static,从而不再需要对象实例就能调用。

普通lambda

auto l = [] { return 42; };
// 等价于:struct { int operator()() const; };

C++23 static lambda

auto l = [] static { return 42; };
// 等价于:struct { static int operator()(); };

调用方式

int a = l();                 // 仍然可以
int b = decltype(l)::operator()(); // 无需对象实例

不需要构造lambda对象、天然无状态、行为接近constexpr普通函数。

constexpr 再扩展

更多标准库函数、容器在 C++23 中变为 constexpr, 如 std::vectorstd::stringstd::optional 等。

编译期构建复杂数据结构成为可能。

std::print std::println

#include <print>
std::println("Hello {}, hp={}", name, hp);

轻量输出,基于 std::format

std::ranges::to

auto v = some_range | std::ranges::to<std::vector>();

ranges结果一行转容器。

std::expected

std::expected<int, std::string> parse(std::string_view s);

if (auto r = parse("123")) {
    use(*r);
} else {
    log(r.error());
}

现代错误处理,替代异常、返回码。

#include <expected>
#include <charconv>
#include <string>
#include <string_view>

std::expected<int, std::string> parse(std::string_view s) {
    int v{};
    auto [p, ec] = std::from_chars(s.data(), s.data() + s.size(), v);
    if (ec == std::errc{})
        return v;
    return std::unexpected("invalid integer");
}

if (auto r = parse("42")) {
    static_assert(std::is_same_v<decltype(*r), int>);
    std::cout << *r << '\n';
} else {
    std::cerr << r.error() << '\n';
}

std::mdspan

高性能多维数组视图。

std::mdspan<int, std::extents<size_t, 3, 4>> m(data);
m(1,2) = 5;

std::flat_map std::flat_set

小数据量下更 cache-friendly 的关联容器。

std::stacktrace

#include <stacktrace>
auto st = std::stacktrace::current();
std::cout << st;

崩溃/日志定位利器。

std::generator

std::generator<int> gen() {
    for (int i = 0; i < 5; ++i)
        co_yield i;
}

基于协程的惰性序列。

std::move_only_function

std::move_only_function<void()> f =
    [p = std::make_unique<int>(1)] { /* ... */ };

任务系统、回调更高效。

枚举与工具函数

std::to_underlying

std::is_scoped_enum

std::byteswap

std::unreachable

字符串增强

if (s.contains("error")) {}

支持

std::string::contains

std::string_view::contains

<chrono>ranges/algorithms 持续补全

日历、时间、算法、视图大量小增强。