noexcept
运算符 (C++11 起)
来自cppreference.com
noexcept 运算符进行编译时检查,在表达式声明不会抛出任何异常的情况下返回 true。
它可用于函数模板的 noexcept 说明符中,以声明函数将对某些类型抛出异常,但不对其他类型抛出。
语法
noexcept( 表达式 )
|
|||||||||
返回 bool 类型的纯右值。如果 表达式 的潜在异常集合为空 (C++17 前)表达式 指定为不会抛出 (C++17 起),那么结果是 true,否则结果是 false。
表达式 是不求值操作数。
如果表达式 是纯右值,那么就会进行临时量实质化。 |
(C++17 起) |
注解
即使 noexcept(expr) 是 true,对 expr 进行求值仍然有可能由于碰到了未定义行为而抛出异常。
如果表达式 具有类类型或它的(可能多维的)数组类型,那么临时量实质化要求析构函数未被弃置且可访问。 |
(C++17 起) |
关键词
示例
运行此代码
#include <iostream> #include <utility> #include <vector> void may_throw(); void no_throw() noexcept; auto lmay_throw = []{}; auto lno_throw = []() noexcept {}; class T { public: ~T(){} // 析构函数妨碍了移动构造函数 // 复制构造函数不会抛出异常 }; class U { public: ~U(){} // 析构函数妨碍了移动构造函数 // 复制构造函数可能会抛出异常 std::vector<int> v; }; class V { public: std::vector<int> v; }; int main() { T t; U u; V v; std::cout << std::boolalpha << "may_throw() 可能会抛出异常吗?" << !noexcept(may_throw()) << '\n' << "no_throw() 可能会抛出异常吗?" << !noexcept(no_throw()) << '\n' << "lmay_throw() 可能会抛出异常吗?" << !noexcept(lmay_throw()) << '\n' << "lno_throw() 可能会抛出异常吗?" << !noexcept(lno_throw()) << '\n' << "~T() 可能会抛出异常吗?" << !noexcept(std::declval<T>().~T()) << '\n' // 注:以下各项测试也要求 ~T() 不会抛出异常 // 因为 noexcept 中的表达式会构造并销毁临时量 << "T(T 右值) 可能会抛出异常吗?" << !noexcept(T(std::declval<T>())) << '\n' << "T(T 左值) 可能会抛出异常吗?" << !noexcept(T(t)) << '\n' << "U(U 右值) 可能会抛出异常吗?" << !noexcept(U(std::declval<U>())) << '\n' << "U(U 左值) 可能会抛出异常吗?" << !noexcept(U(u)) << '\n' << "V(V 右值) 可能会抛出异常吗?" << !noexcept(V(std::declval<V>())) << '\n' << "V(V 左值) 可能会抛出异常吗?" << !noexcept(V(v)) << '\n'; }
输出:
may_throw() 可能会抛出异常吗?true no_throw() 可能会抛出异常吗?false lmay_throw() 可能会抛出异常吗?true lno_throw() 可能会抛出异常吗?false ~T() 可能会抛出异常吗?false T(T 右值) 可能会抛出异常吗?false T(T 左值) 可能会抛出异常吗?false U(U 右值) 可能会抛出异常吗?true U(U 左值) 可能会抛出异常吗?true V(V 右值) 可能会抛出异常吗?false V(V 左值) 可能会抛出异常吗?true
缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
缺陷报告 | 应用于 | 出版时的行为 | 正确行为 |
---|---|---|---|
CWG 2722 | C++17 | 不明确在表达式 是纯右值时是否会进行临时量实质化 | 此时会进行临时量实质化 |
CWG 2792 | C++11 | noexcept 运算符需要确定在碰到未定义行为时是否会抛出异常 | 不需要确定 |
参阅
noexcept 说明符(C++11)
|
指定函数是否可以抛出异常 |
动态异常说明(C++17 前) | 指定函数所抛出的异常 (C++11 中弃用) |