写点什么

这可能是近十年最重要的 C++ 版本更新,反射、契约、并发模型全面进化

  • 2026-04-18
    北京
  • 本文字数:1405 字

    阅读完需:约 5 分钟

长期从事 C++ 的专家、前 ISO C++ 标准委员会主席 Herb Sutter 表示,C++26 标准草案现已完成。最终版本的草案引入了反射,在无需重写代码的情况下增强了内存安全性,新增了包含前置条件和后置条件的契约以及一种新的断言语句,并建立了一个统一的并发与并行框架。

反射是一种机制,正如 Sutter 所解释的,它赋予开发者访问 C++ 内部机制的能力,使语言能够描述自身并生成代码,从而为元编程提供坚实基础。秉承 C++ 的精神,反射不会带来任何运行时开销。作为反射能力的一个基本示例,下面的代码片段展示了反射如何支持一种用于声明 C++ 接口的专用语法:

class(interface) IFoo {    int f();    void g(std::string);};//-- will be translated into the "classical":class IFoo {    public:      virtual int f() = 0;      virtual void g(std::string) = 0;      virtual ~IFoo() = default;      IFoo() = default;    protected:      IFoo(IFoo const&) = default;      void operator=(IFoo const&) = default;};
复制代码

反射可以通过减少对大量定制化新语言特性的需求来简化 C++的未来演进,因为许多特性现在都可以表示为可复用的编译期库,设计更快、测试更容易,并且从一开始就具备可移植性。

接口抽象是 cppfront 的一部分,cppfront 是一个可编译为纯 ISO C++ 的编译器,由 Sutter 创建,用于提供一种更快速的提案实验方式。它还包括诸如 copyable(用于表达支持复制/移动构造与赋值的类型)、ordered(用于定义带有 operator<=> 的全序类型)、union(用于带名称的标签联合)、regex 等抽象,以及更多内容。

C++26 旨在带来显著改进的另一个领域是内存安全。这包括开箱即用地消除读取未初始化局部变量时的未定义行为,以及为大多数标准库类型(包括 vector、span、string、string_view)提供边界安全。Sutter 表示,这些改动已经在 Apple 和 Google 的生产环境中部署,覆盖了数亿行 C++ 代码:

这并非纸上谈兵。仅在 Google 内部,它已经修复了超过 1000 个缺陷,预计每年可防止 1000 到 2000 个缺陷,并将生产环境中的段错误发生率降低了 30%。

更重要的是,这些收益仅通过使用新编译器重新编译现有代码即可获得。只有在七个案例中,编译器无法分析高度优化的代码,需要开发者使用细粒度 API 在这些特定部分选择性地退出内存安全机制。

C++26 契约将防御式编程引入语言本身,提升了功能安全性和内存安全性。它允许开发者表达在方法执行过程中不可被违反的前置条件和后置条件。契约使断言可以移动到函数声明中,从而对调用者和静态分析工具可见。C++ 提供了四种处理契约违规的方式:忽略(ignore)、观察(observe)、强制(enforce)以及快速强制(quick enforce)。此外,它还引入了原生断言机制,用以替代 C 的 assert 宏。

最后,C++26 引入了 std::execution,作为一个用于表达和控制并发与并行的框架。该框架的三个主要抽象是调度器(schedulers)、发送器(senders)和接收器(receivers),它们可以通过一组可定制的异步算法进行组合。std::execution 被设计为能够很好地与 C++20 协程协同工作,并使编写“使用结构化(严格生命周期嵌套)的并发与并行、从构造上避免数据竞争的程序”变得更加容易。

两大主流 C++ 编译器 GCC 和 Clang 已经在标准制定过程中实现了 C++26 的大部分特性,这些特性很快将进入主线版本。

原文链接:

https://www.infoq.com/news/2026/04/cpp-26-reflection-safety-async/