警告 C26440

函数可以声明为“noexcept”。

C++ Core Guidelines F.6:如果未引发函数,请将其声明为 noexcept

如果代码不应引起任何异常,则应使用 noexcept 说明符标记此代码。 此注释有助于简化客户代码端上的错误处理,并使编译器能够执行更多优化。

注解

  • 将函数视为不引发的情况如下:
    • 函数没有显式 throw 语句;
    • 正文中的函数调用(如果有)仅调用不太可能引发的函数:constexpr 或标有任何异常规范且该规范将产生非引发行为的函数(包括一些非标准规范)。
  • 非标准和过时的说明符(例如 throw()__declspec(nothrow))不等同于 noexcept
  • 合理遵循显式说明符 noexcept(false)noexcept(true)
  • 标记为 constexpr 的函数不应导致异常,也不会对其进行分析。
  • 该规则也适用于 lambda 表达式。
  • 逻辑不认为递归调用可能是非引发的。 在将来,该逻辑可能会有变化。

示例

除析构函数之外的所有函数都会发出警告,因为它们缺少 noexcept。

struct S
{
    S() {} // C26455, Default constructor may not throw. Declare it 'noexcept'
    ~S() {}

    S(S&& s) {/*impl*/} // C26439, This kind of function may not throw. Declare it 'noexcept' (f.6)
    S& operator=(S&& s) {/*impl*/} // C26439, This kind of function may not throw. Declare it 'noexcept' (f.6)

    S(const S& s) {/*impl*/} // C26440, This function can be declared 'noexcept'
    S& operator=(const S& s) {/*impl*/} // C26440, This function can be declared 'noexcept'
};

使用 noexcept 修饰相同的结构,将删除所有警告。

struct S
{
    S() noexcept {}
    ~S() {}

    S(S&& s) noexcept {/*impl*/}
    S& operator=(S&& s) noexcept {/*impl*/}

    S(const S& s) noexcept {/*impl*/}
    S& operator=(const S& s) noexcept {/*impl*/}
};