第 12 章 C++26(展望)

重要提示:截至本章撰写时,C++26 仍处于最终定稿阶段(其国际标准草案 DIS 预计于 2026 年前后完成),标准内容仍可能调整。同时,绝大多数 C++26 特性在当前主流编译器与标准库中尚未实现或仍处于实验阶段。因此本章是一个前瞻性的预览:对于编译器已经支持的特性,我们给出可运行的示例;对于尚未落地的重磅特性,我们仅介绍其设计意图与大致语法。一切请以 cppreference: C++26 为准。

C++26 被许多人寄予厚望,因为它有望带来反射、契约、std::execution 等酝酿多年的重大特性。下面我们分别介绍。

12.1 语言特性

静态反射(Reflection)

反射或许是 C++26 最受期待的特性。它允许程序在编译期以一等公民的方式检视并操作程序自身的结构(类型、成员、枚举项等),从而以标准化的方式实现以往依赖宏或外部代码生成器才能完成的工作。其设计引入了反射运算符 ^^(取得表示某实体的 std::meta::info 值)以及「拼接」语法 [: ... :](将反射值重新变回代码):

// 概念性示例(语法以最终标准为准)
constexpr auto r = ^^int; // 取得表示 int 的反射值
typename [: r :] x = 42; // 通过拼接将反射值变回类型 int

反射尚未在主流工具链中可用,上述代码目前无法编译,仅用于说明其形态。

契约(Contracts)

契约为函数引入了语言级的前置条件后置条件与断言,用于以可被工具识别的方式表达并检查接口约定:

// 概念性示例
int divide(int a, int b)
pre(b != 0) // 前置条件
post(r: r * b <= a) // 后置条件(r 为返回值)
{
contract_assert(b != 0); // 语句级断言
return a / b;
}

契约曾在 C++20 阶段被移除,如今重新瞄准 C++26。它同样尚未在主流工具链中可用。

形参包索引

C++26 允许直接用 pack...[N] 的语法索引一个形参包中的第 N 个元素,从此不必再借助递归或 std::tuple 的层层展开:

template <typename... Ts>
auto first(Ts... ts) { return ts...[0]; }

template <typename... Ts>
auto last(Ts... ts) { return ts...[sizeof...(ts) - 1]; }

带原因的 = delete

C++26 允许在删除函数时附上一条原因字符串,当该重载被选中时,编译器会把这条原因一并报告,从而给出更友好的错误信息:

void use_span(int* p, int n);
void use_span(std::nullptr_t) = delete("pass a real buffer, not nullptr");

占位符 _

C++26 将 _ 规定为占位符名称:它可以在同一作用域内被重复声明,用于明确表达「这个值我并不关心」,例如结构化绑定中不需要的部分:

auto _ = compute();   // 我不关心返回值
auto _ = compute(); // C++26 允许再次以 _ 声明

12.2 标准库

std::execution(发送者 / 接收者)

std::execution(即提案 P2300,常被称为「发送者/接收者」(senders/receivers) 模型)为异步与并行计算提供了一套标准化、可组合的执行框架,被视为现代 C++ 异步编程的基石之一。

该框架尚未广泛落地于标准库实现,故本章不提供可运行示例。

饱和算术

C++26 在 <numeric> 中加入了饱和算术函数 std::add_satstd::sub_satstd::mul_satstd::div_sat 以及 std::saturate_cast。与普通整数运算在溢出时回绕(wrap around)不同,饱和运算会在溢出时钳制 (clamp) 到该类型可表示的最大或最小值:

#include <numeric>
#include <limits>

int hi = std::numeric_limits<int>::max();
std::add_sat(hi, 1); // 结果为 INT_MAX,而非回绕为负数
std::sub_sat(0, 1); // -1

其他库设施

C++26 还计划带来许多新的库设施,包括:

这些设施在当前标准库中大多尚未实现;其中个别设施(如 std::hive)是否会最终纳入 C++26 仍存在不确定性,请以最终标准与 cppreference 为准。

其他值得关注的提案

除上述特性外,C++26 还在语言与库两方面带来许多改进,例如:

同样地,这些提案的最终形态与纳入与否仍以最终标准为准。

12.3 关于标准与实现状态

再次强调:C++26 尚未正式发布,本章所述特性的最终语法与是否纳入标准都可能发生变化,且当前能够编译运行的仅是其中一小部分(如形参包索引、带原因的 = delete、占位符 _、饱和算术)。建议读者持续关注 cppreference: C++26编译器支持情况 以获取最新进展。

总结

C++26 有望成为继 C++11、C++20 之后又一个里程碑式的版本——反射与契约若能如期落地,将再次深刻地改变我们编写 C++ 的方式。在它正式到来之前,保持关注、谨慎尝试,便是最好的准备。

进一步阅读的参考资料