C++20那些事之constexpr与comma expr

C++20那些事之constexpr与comma expr

C++20 引入了多项新特性,进一步增强了编译时能力和代码安全性。本文将深入探讨两项重要的变更:constexpr 函数中的异常处理 以及下标运算符中逗号运算符的弃用

注:懒人版,本节的代码示例与相关文档已更新在星球,感兴趣加入即可。

1. constexpr 函数中支持 try-catch 异常处理的变更

在 C++20 之前,constexpr 函数中不能使用 try-catch 块,这一限制阻碍了一些标准库容器如 std::array 的编译时处理能力。C++20 对此进行了改进,允许在 constexpr 函数中使用 try-catch 块,并且在常量表达式的上下文中忽略这些异常处理结构。当在常量表达式计算中抛出异常时,编译器会报错。

这项改动的主要目的是让标准库中的容器能够支持 constexpr,例如 std::array,同时为将来在编译时支持更多异常处理提供了基础。

示例

go 复制代码
constexpr int SafeDivide(int a, int b) {
    if (b == 0) {
        throw std::runtime_error("Division by zero!");  // 当除数为0时抛出异常
    }
    return a / b;
}

constexpr int ComputeQuotient(int x) {
    try {
        return SafeDivide(100, x);  // 尝试除法运算
    } catch (const std::runtime_error&) {
        return -1;  // 捕获除零异常并返回 -1
    }
}

上面代码在C++20之前编译不过,那么C++20对这个行为是什么呢,可以猜一下下面两个结果:

go 复制代码
static_assert(ComputeQuotient(25) == 4); 
static_assert(ComputeQuotient(0) == -1);
2. 下标运算符中的逗号运算符弃用

C++20 的另一项变更是弃用在下标运算符中使用逗号运算符 。在早期的 C++ 版本中,表达式 array[x, y] 中,逗号运算符会使 y 作为下标传递给数组或容器,而 x 被忽略。然而,这种用法会导致代码不易理解,并且妨碍未来多维数组的实现。因此,自 C++20 起,下标运算符中的逗号运算符被弃用 ,除非使用括号明确指定优先级,如 array[(x, y)]

示例代码

go 复制代码
// arr[i, j] = 10;  // C++17 中合法,C++20 中弃用
arr[(i, j)] = 10;  // 使用括号以明确逗号的优先级

在这个例子中,arr[(i, j)] 使用了括号以明确逗号运算符的优先级,确保 j 作为下标传递给数组。在 C++17 中,arr[i, j] 是允许的,但在 C++20 中,这样的用法会触发弃用警告。通过这种方式可以确保代码的行为一致,并符合 C++20 的新标准。

如果使用了逗号运算符编译器将会警告:

go 复制代码
common.cc:9:10: warning: top-level comma expression in array subscript is deprecated [-Wcomma-subscript]
    9 |     arr[i, j] = 10;  // C++17 中合法,C++20 中弃用
      |          ^

总结

C++20 中的这些变更,特别是 constexpr 函数中的异常处理支持和下标运算符中逗号运算符的弃用,都是为了提升编译时能力和代码的可读性。如果你的代码依赖这些旧特性,建议及时进行调整,以适应 C++20 的新标准。

一起探索更多C++项目/知识~

往期推荐:

向量数据库milvus源码剖析之开篇

热度更新,手把手实现工业级线程池

玩转cpp小项目星球3周年了!

相关推荐
ashane13148 小时前
Springboot 启动过程及源码分析
java·spring boot·后端
caron49 小时前
c++ -- 循环依赖解决方案
java·c++·算法
七夜zippoe9 小时前
深入理解Java泛型:类型擦除、通配符PECS原则与实践
java·泛型·通配符·类型擦除·pecs
消失的旧时光-19439 小时前
Kotlin JSON 序列化库选型指南:Kotlinx.serialization vs Gson
开发语言·kotlin·json
newchenxf9 小时前
AndroidStudio版本和AGP版本和gradle版本以及kotlin gradle plugin版本关系梳理 2025
android·开发语言·kotlin
后端小张9 小时前
【JAVA进阶】SpringBoot启动流程深度解析:从main方法到应用就绪的完整旅程
java·spring boot·后端·spring·spring cloud·java-ee·流程分析
猫头虎9 小时前
Rust评测案例:Rust、Java、Python、Go、C++ 实现五大排序算法的执行时间效率比较(基于 OnlineGDB 平台)
java·开发语言·c++·python·golang·rust·排序算法
爱吃烤鸡翅的酸菜鱼9 小时前
【Java】基于策略模式 + 工厂模式多设计模式下:重构租房系统核心之城市房源列表缓存与高性能筛选
java·redis·后端·缓存·设计模式·重构·策略模式
milanyangbo9 小时前
从局部性原理到一致性模型:深入剖析缓存设计的核心权衡
开发语言·后端·缓存·架构
WangY_ZQ9 小时前
eclipse maven 项目 提示 http://maven.apache.org/xsd/maven-4.0.0.xsd‘
java