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