警告 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*/}
};