错误处理是软件开发中最容易被忽视也最容易出问题的部分。C++ 提供了多种错误处理机制:异常、错误码、断言以及 C++23 引入的 std::expected。选择正确的策略对代码的健壮性至关重要。
异常的三种安全保证
- 基本保证:发生异常时,所有对象保持有效状态,无资源泄漏。
- 强保证:操作要么完全成功,要么将状态回滚到操作前(类似事务)。
- 不抛出保证:操作保证不会抛出异常(标记为 noexcept)。
noexcept 的用途
noexcept 不仅是文档,还影响编译器优化。移动构造函数标记为 noexcept 可以让 std::vector 在扩容时安全地使用移动而非拷贝。如果移动操作可能抛异常,vector 会退化为拷贝以保证强异常安全。
class MyClass {
public:
MyClass(MyClass&&) noexcept = default; // 保证不抛异常
MyClass& operator=(MyClass&&) noexcept = default;
};
C++23: std::expected
std::expected<T, E> 是 C++23 引入的结果类型,要么包含成功值 T,要么包含错误值 E。类似于 Rust 的 Result 或 Haskell 的 Either,它把错误处理从隐式的控制流变为了显式的值传递,让错误路径不可忽视。
错误处理不应该是一条被遗忘的分支——它也是代码逻辑的重要组成部分。