Namespaces
Variants

noexcept operator (since C++11)

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

noexcept 运算符执行编译时检查,若表达式被声明为不抛出任何异常则返回 true

它可以在函数模板的 noexcept 说明符 中使用,用于声明该函数对于某些类型会抛出异常,而对于其他类型则不会。

目录

语法

noexcept( 表达式 )

返回一个类型为 bool 纯右值 。若 表达式 潜在异常集合 为空 (C++17 前) 表达式 被指定为 不抛出 (C++17 起) ,则结果为 true ,否则为 false

expression 是一个 unevaluated operand

如果 expression 是纯右值,则应用 临时物化

(since C++17)

注释

即使 noexcept ( expr ) true ,对 expr 的求值仍可能因遇到未定义行为而抛出异常。

expression 为类类型或其(可能多维的)数组类型,则临时物化要求析构函数未被删除且可访问。

(since 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(){} // 析构函数阻止移动构造函数
           // 拷贝构造函数为 noexcept
};
class U
{
public:
    ~U(){} // 析构函数阻止移动构造函数
           // 拷贝构造函数为 noexcept(false)
    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() is noexcept(" << noexcept(may_throw()) << ")\n"
        "no_throw() is noexcept(" << noexcept(no_throw()) << ")\n"
        "lmay_throw() is noexcept(" << noexcept(lmay_throw()) << ")\n"
        "lno_throw() is noexcept(" << noexcept(lno_throw()) << ")\n"
        "~T() is noexcept(" << noexcept(std::declval<T>().~T()) << ")\n"
        // 注意:以下测试还需要 ~T() 为 noexcept,因为
        // noexcept 内的表达式会构造并销毁临时对象
        "T(rvalue T) is noexcept(" << noexcept(T(std::declval<T>())) << ")\n"
        "T(lvalue T) is noexcept(" << noexcept(T(t)) << ")\n"
        "U(rvalue U) is noexcept(" << noexcept(U(std::declval<U>())) << ")\n"
        "U(lvalue U) is noexcept(" << noexcept(U(u)) << ")\n"
        "V(rvalue V) is noexcept(" << noexcept(V(std::declval<V>())) << ")\n"
        "V(lvalue V) is noexcept(" << noexcept(V(v)) << ")\n";
}

输出:

may_throw() is noexcept(false)
no_throw() is noexcept(true)
lmay_throw() is noexcept(false)
lno_throw() is noexcept(true)
~T() is noexcept(true)
T(rvalue T) is noexcept(true)
T(lvalue T) is noexcept(true)
U(rvalue U) is noexcept(false)
U(lvalue U) is noexcept(false)
V(rvalue V) is noexcept(true)
V(lvalue V) is noexcept(false)

缺陷报告

下列行为变更缺陷报告被追溯应用于先前发布的C++标准。

缺陷报告 适用标准 已发布行为 正确行为
CWG 2722 C++17 表达式 为纯右值时,是否应用临时物化语义不明确 在此情况下
应当应用
CWG 2792 C++11 noexcept 运算符需要判定遇到未定义行为时
是否可能抛出异常
无需判定

参见

noexcept 说明符 (C++11) 指定函数是否会抛出异常
动态异常规范 (C++17 前) 指定函数会抛出哪些异常 (C++11 起弃用)