C++26 constexpr 异常详解:编译期也能 throw/catch

C++26 constexpr 异常详解:编译期也能 throw/catch

本文是「C++26 新特性单篇精讲」系列第 4 篇。阅读约需 6 分钟,文末可跳转完整合订本。


一、是什么

C++26 允许在 constexpr 函数中使用 try/throw/catch。未捕获的编译期异常会转化为带具体错误信息的编译错误。


二、为什么需要它

此前 constexpr 函数里一旦 throw,编译器直接报错。复杂编译期算法只能用哨兵值或 static_assert(false, ...),错误信息不精确。

constexpr 异常让编译期代码的错误处理与运行时一样自然,未捕获异常还能给出更清晰的诊断。


三、完整代码示例

3.1 编译期除法

cpp 复制代码
#include <stdexcept>
#include <optional>

constexpr unsigned divide(unsigned n, unsigned d) {
    if (d == 0) {
        throw std::invalid_argument("division by zero");
    }
    return n / d;
}

// 未捕获异常 → 编译错误,提示 "division by zero"
// constexpr auto a = divide(5, 0);  // 编译失败

constexpr std::optional<unsigned> safe_divide(unsigned n, unsigned d) {
    try {
        return divide(n, d);
    } catch (...) {
        return std::nullopt;
    }
}

constexpr auto ok = safe_divide(10, 2);   // 5
constexpr auto fail = safe_divide(10, 0); // std::nullopt

static_assert(ok.value() == 5);
static_assert(!fail.has_value());

int main() {}

3.2 配置校验场景

cpp 复制代码
constexpr int parse_port(int p) {
    if (p <= 0 || p > 65535) {
        throw std::out_of_range("port must be in [1, 65535]");
    }
    return p;
}

constexpr int port = parse_port(8080);  // OK
// constexpr int bad = parse_port(70000); // 编译错误

四、编译器支持与特性测试宏

编译器 版本
GCC 15+
Clang 19+
MSVC 19.50+
cpp 复制代码
#if __cpp_constexpr_exceptions >= 202411L
// constexpr 异常可用
#endif

五、常见陷阱

  1. 不能逃逸到运行时:编译期异常必须在编译期被捕获;
  2. 运行时调用仍正常 :constexpr 函数在运行时调用时,throw 行为与往常一样;
  3. 析构函数要求 :编译期抛出的对象必须有 constexpr 析构函数。

六、小结

constexpr 异常让编译期编程拥有正常的错误处理语义,是 C++26 元编程能力的重要拼图。适合配置校验、编译期算法、模板参数检查等场景。


本文基于 C++26 已批准特性撰写,具体实现以编译器文档为准。

相关推荐
一条破秋裤7 小时前
Linux 线程分离与主动取消:pthread_detach、pthread_cancel
java·linux·jvm
茉莉玫瑰花茶7 小时前
OpenGL [ 基础概念 ]
java·前端·数据库
周杰偷奶茶7 小时前
【Java】运算符指南
java·开发语言
随性而行3607 小时前
企业微信二次开发如何接入大模型工具?API接口实现智能任务调用的技术思路
java·前端·人工智能·python·微信·机器人·企业微信
单片机设计·······7 小时前
【dz-1162】汽车前玻璃雨刮器设计
c++·单片机·嵌入式硬件
AI智讯中枢8 小时前
高性能 C++ 实战 (五):perf+FlameGraph 火焰图生产实战,精准定位 CPU / 缓存 / 锁瓶颈,避坑 + 完整实操案例
linux·c++·性能调优·性能分析·perf·flamegraph·火焰图
繁华的地方不一定留下你的脚印8 小时前
C++ 算法与 ranges:用 find_if、transform 写清数据处理意图
开发语言·c++·算法
张小姐的猫8 小时前
【AI大模型接入SDK】 —— 前端页面 & 项目总结与拓展
前端·数据结构·数据库·c++·人工智能·chatgpt
Json____8 小时前
基于 Spring Boot + Vue3 的在线考试管理系统实战
java·spring boot·后端·it学习·wwwoop.com
weixin_537590458 小时前
《Spring快速入门到精通》- 实例1.1
java·spring·intellij-idea