noexcept
Version >= C++ 11
-
一元运算符,用于确定对其操作数的求值是否可以传播异常。请注意,不检查被调用函数的主体,因此
noexcept
可以产生错误否定。不评估操作数。#include <iostream> #include <stdexcept> void foo() { throw std::runtime_error("oops"); } void bar() {} struct S {}; int main() { std::cout << noexcept(foo()) << '\n'; // prints 0 std::cout << noexcept(bar()) << '\n'; // prints 0 std::cout << noexcept(1 + 1) << '\n'; // prints 1 std::cout << noexcept(S()) << '\n'; // prints 1 }
在这个例子中,即使
bar()
永远不会抛出异常,noexcept(bar())
仍然是假的,因为bar()
无法传播异常这一事实尚未明确指定。 -
声明函数时,指定函数是否可以传播异常。单独地,它声明该函数不能传播异常。使用带括号的参数,它声明函数可以或不可以根据参数的真值传播异常。
void f1() { throw std::runtime_error("oops"); } void f2() noexcept(false) { throw std::runtime_error("oops"); } void f3() {} void f4() noexcept {} void f5() noexcept(true) {} void f6() noexcept { try { f1(); } catch (const std::runtime_error&) {} }
在这个例子中,我们声明
f4
,f5
和f6
不能传播异常。 (虽然在执行f6
期间可以抛出异常,但它被捕获并且不允许传播出函数。)我们已经声明f2
可能传播异常。当noexcept
说明符被省略时,它相当于noexcept(false)
,所以我们隐含地声明f1
和f3
可以传播异常,即使在执行f3
期间实际上不能抛出异常。
Version >= C++ 17
函数是否为 noexcept
是函数类型的一部分:即,在上面的示例中,f1
,f2
和 f3
具有与 f4
,f5
和 f6
不同的类型。因此,noexcept
在函数指针,模板参数等方面也很重要。
void g1() {}
void g2() noexcept {}
void (*p1)() noexcept = &g1; // ill-formed, since g1 is not noexcept
void (*p2)() noexcept = &g2; // ok; types match
void (*p3)() = &g1; // ok; types match
void (*p4)() = &g2; // ok; implicit conversion