noexcept 运算符 (C++11 起)

来自cppreference.com
< cpp‎ | language


 
 
C++ 语言
 
异常
try
抛出异常
处理异常
异常说明
    noexcept 说明 (C++11)
    动态说明 (C++17 前*)
noexcept 运算符 (C++11)
 

noexcept 运算符进行编译时检查,在表达式声明不会抛出任何异常的情况下返回 true

它可用于函数模板的 noexcept 说明符中,以声明函数将对某些类型抛出异常,但不对其他类型抛出。

语法

noexcept( 表达式 )

返回 bool 类型的纯右值。如果 表达式 的潜在异常集合为空 (C++17 前)表达式 指定为不会抛出 (C++17 起),那么结果是 true,否则结果是 false

表达式 是不求值操作数

如果表达式 是纯右值,那么就会进行临时量实质化

(C++17 起)

注解

即使 noexcept(expr)true,对 expr 进行求值仍然有可能由于碰到了未定义行为而抛出异常。

如果表达式 具有类类型或它的(可能多维的)数组类型,那么临时量实质化要求析构函数未被弃置且可访问。

(C++17 起)

关键词

noexcept

示例

#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 中弃用)