不能一次性升级到C++20,必须分阶段控制ABI变更、接口稳定性与编译器支持边界;最稳妥路径是先稳住C++11/14的RAII和智能指针,再用C++17的if constexpr和结构化绑定解耦逻辑,最后在关键模块试探C++20的std::span、std::expected和Modules。

直接说结论:不能一次性升级到 C++20,必须分阶段控制 ABI 变更、接口稳定性与编译器支持边界;最稳妥的路径是先稳住 C++11/14 的 RAII 和智能指针,再用 C++17 的 if constexpr 和结构化绑定解耦逻辑,最后在关键模块试探 C++20 的 std::span、std::expected 和 Modules——前提是你的构建链和下游依赖已准备好。
为什么不能跳过 C++11/14 直接上 C++20
C++98 到 C++20 不是版本号递增,而是 ABI 断层叠加语义迁移。比如:
-
std::string在 GCC 5(C++11)起默认启用 SSO,但其内部布局在 C++17 后又因std::string_view引入而微调;若头文件暴露了std::string成员,升级 -std=c++20 就可能让旧 .so 加载失败 - C++20 的
concept会改变模板实例化规则,一旦你导出一个用了requires的模板函数,所有调用它的 C++17 客户端将链接失败 - MSVC 对 C++20 Modules 的 ABI 支持仍不完全兼容 Clang/GCC,跨团队协作时极易卡在
module not found或隐式导入失败
第一步:用 C++11/14 特性封住内存泄漏和资源裸奔
这是重构的“止血点”,目标是让代码在不改行为的前提下获得异常安全和自动释放能力。重点不是语法炫技,而是堵住高频崩溃口:
- 把所有
new/delete对替换成std::unique_ptr或std::shared_ptr,尤其注意工厂函数返回的裸指针——它们常是 ABI 破坏源头 - 用
std::vector替代手写的int*+size_t组合,但别直接暴露std::vector成员到头文件;改用 Pimpl 模式藏进Impl类里 - 把
typedef全部换成using,它在模板中更稳定,且不会因宏展开顺序错乱导致类型别名失效 - 禁用
NULL,统一用nullptr;这看似小改动,但能避免某些老编译器在重载解析时误选int版本函数
第二步:用 C++17 特性消除条件编译和冗余模板实例
这个阶段的目标是让逻辑更清晰、编译更快,同时不引入新 ABI 风险:
立即学习“C++免费学习笔记(深入)”;
- 把
#ifdef _WIN32包裹的大段平台分支,改成if constexpr (std::is_same_v<t windowsplatform>)</t>—— 编译期剪枝后,生成代码体积更小,且不会因宏污染导致头文件重复定义 - 用结构化绑定替代
std::pair::first/second访问:例如for (const auto& [key, value] : my_map),它不改变 ABI,但大幅降低迭代器误用概率 - 把长函数里的
static_cast替换为auto推导(配合-Wold-style-cast警告),避免 C 风格强制转换绕过类型检查 - 慎用
std::optional:它虽是 C++17,但其内存布局在不同标准库实现间不保证一致;如需跨 DLL 使用,应封装成私有成员 + 公共 getter/setter
第三步:C++20 的落地要卡在“模块边界”而非“语法糖”
C++20 最值得投入的不是 coroutine,而是 Modules 和 std::span 这类能真正隔离变更面的特性:
- 优先对新写的工具模块(如日志、配置解析)启用
module,老代码继续用#include;不要试图把整个legacy_api.h改成 module interface,那等于重写 ABI -
std::span可安全替代T*+size_t参数对,但它本身是纯头文件设施,不引入 ABI 依赖——只要你不把它作为类成员公开出去 -
std::expected很好,但目前主流标准库(libstdc++、libc++)对其 ABI 尚未冻结;生产环境建议先用自定义expected模板,或仅在内部函数返回值中使用,对外仍保持bool+out param模式 - 别碰
concept导出接口;如果真要用,只在 .cpp 文件内做约束,头文件里保留传统模板声明
最容易被忽略的一点:C++20 的 [[nodiscard]] 和 [[maybe_unused]] 看似无害,但某些嵌入式交叉编译器(如 ARM GCC 9.3)会因不识别这些属性而静默忽略,导致编译通过但警告失效——务必在 CI 中用 -Wattributes 显式捕获。


















