Skip to the content.

C++ Core Guidelines 中文整理

原文:C++ Core Guidelines。 编辑:Bjarne Stroustrup、Herb Sutter。整理日期:2026-09-05;原文页首日期:2026-06-14。 本文按原文章节提炼重点,不是逐条全文翻译。所有编号均保留原文含义,点击编号可查看理由、示例、例外和检查建议。 全部带编号的规则标题另见 规则索引,来源和授权见文末。

阅读方式与总览

Core Guidelines 关注接口、资源、生命周期、类型安全和并发,适合作为设计与代码审查的参考。 它不是 ISO C++ 标准,也不是语言教程;合法的 C++ 写法也可能违反这些建议。 原文以 C++20 为当前基线,多数建议也适用于 C++11/14/17,但部分内容仍引用 GSL、提案或未完成的设计。

章节 主要问题
P:设计理念 怎样让意图、约束和资源关系直接体现在代码中
I:接口 调用者需要知道什么,类型能约束什么
F:函数 参数、返回值和捕获方式如何表达语义
C:类与继承 不变量、特殊成员函数与多态生命周期
Enum:枚举 用类型表达有限取值集合
R:资源管理 谁拥有资源,谁负责释放
ES:表达式与语句 初始化、求值顺序、转换和整数运算
Per:性能 如何根据测量优化数据与执行路径
CP:并发与并行 共享状态、锁、线程与协程的生命周期
E:错误处理 失败后如何维持不变量并释放资源
Con:常量与不可变性 哪些状态允许改变
T:模板与泛型 如何表达类型要求并控制模板复杂度
CPL / SF / SL C 接口、文件组织和标准库
支撑章节 架构、误区、安全配置、GSL、工具和迁移

建议先读 I、F、R、C、E,再按工作需要阅读 CP、T、Per。 与本目录的 Effective C++ 和 Effective Modern C++ 对照阅读时,应保留各自的标准版本与适用条件。

P:设计理念

I:接口

F:函数

职责与声明

参数与返回值速查

语义 常见形式 对应规则及注意事项
只读、小且复制便宜 T F.16,不要机械地把小整数改为 const T&
只读、复制成本较高 const T& F.16,需要保存副本时另外考虑复制/移动成本
修改调用者对象 T& F.17,明确输入输出语义
消耗实参的值 X&& F.18,在函数内对具名参数使用 std::move
泛型转发 推导得到的 T&& F.19,使用 std::forward<T> 保留值类别
输出一个结果 返回值 F.20,优先于输出参数
输出多个相关结果 返回具名 struct F.21,字段名说明含义
可为空的借用 T* F.60,调用前判断是否存在
必须非空的指针 not_null<T*> F.23,仍需保证对象存活
连续序列的借用 span<T> F.24,携带长度,不拥有元素
转移独占所有权 unique_ptr<T> F.26,按值接收便宜且语义清楚
共享所有权 shared_ptr<T> F.27,仅在确有共享生命周期需求时使用

返回与 Lambda 生命周期

C:类与继承

类型与不变量

特殊成员函数

多态、容器与运算符

Enum:枚举

R:资源管理

借用的两个检查点:对象是否仍然存在,以及容器修改是否使地址/迭代器失效。 span、string_view、裸指针和引用都不会自动延长被引用对象的生命周期。

ES:表达式与语句

特别注意 ES.23 的例外:std::vector<int>(8) 是八个零,std::vector<int>{8} 是一个值为八的元素。 不要把所有圆括号初始化机械替换为花括号。

Per:性能

实践时同时记录输入规模、构建选项和运行环境。只优化已经测得的热点,同时验证结果仍然正确。

CP:并发与并行

共享状态与线程

协程

按值传入视图或裸指针仍然只是复制借用。跨挂起点还需检查其底层对象,以及成员协程的 this 所指对象是否存活。

E:错误处理

审查异常路径时,除了“会不会泄漏”,还应检查“是否留下半更新的业务状态”。 RAII 负责释放资源,不会自动回滚所有业务修改。

Con:常量与不可变性

const 不等于深度不可变,也不自动保证线程安全;仍需分析间接引用和共享的可变状态。

T:模板与泛型

原文中仍有历史过渡建议和未完成条目,例如 T.101;应结合所用标准和工具链判断,不把草稿视为成熟约定。

CPL:C 风格编程

SF:源文件

SL:标准库

原文的正则、时间等子章节仍较简略,不能由章节存在推断其已经提供完整实践指南。

支撑章节

原文章节 整理要点
A:架构 稳定与易变部分分离,可复用部分形成库,库依赖避免成环
NR:误区 不强制变量集中声明、单一 return、每类一个文件;避免两阶段初始化和末尾集中手动清理
RF:参考资料 书籍、网站、视频和其他规范入口;部分资料年代较早
Pro:安全配置 类型、边界、生命周期三个方向相互配合;属于规则与检查要求,不是编译器自动提供的完整安全保证
GSL:支持库 通过视图、所有权标注、非空类型与断言表达约束;具体实现支持情况需另外核对
NL:命名与布局 注释解释意图、保持风格一致、避免难辨名字;服从项目已有风格
FAQ 解释指南定位、维护方式及 GSL 与标准库的关系
附录 A:库 支持库相关补充,原文尚不完整
附录 B:现代化 渐进改造旧代码,结合工具处理易识别的旧式写法
附录 C:讨论 初始化顺序、工厂、析构、noexcept 与资源安全等深入解释
附录 D:工具 clang-tidy、CppCoreCheck 等检查入口
术语表 查阅术语定义
待整理规则 未分类和待完善内容,不能当作已定稿规则

标准库与 GSL 不要混淆

名称 阅读时需要区分的含义
std::span C++20 连续范围视图;携带长度,不拥有元素;不能假定 C++20 的下标操作自动检查越界
std::string_view C++17 只读字符串视图,不保证零结尾,不延长底层字符串生命周期
gsl::owner<T*> 所有权标注,不等同于有析构管理能力的 unique_ptr
gsl::not_null<T*> 表达非空要求,不能证明对象仍然存活
Expects / Ensures 原文 GSL 风格的前置/后置条件设施,不是 C++20 标准语言契约
gsl::joining_thread 原文的自动 join 线程抽象;C++20 项目也可结合 std::jthread 及其停止请求语义设计

上表是整理时的版本与语义提示;原文中的 span_p、synchronized_value 等名称也不能直接视为标准库现成组件。

代码审查清单

来源与维护

本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。