- 當(dāng)
noexcept是標(biāo)識(shí)符時(shí), 它的作用是在函數(shù)后面聲明一個(gè)函數(shù)是否會(huì)拋出異常.- 當(dāng)
noexcept是函數(shù)時(shí), 它的作用是檢查一個(gè)函數(shù)是否會(huì)拋出異常.備注:
noexcept編譯期完成聲明和檢查工作.
noexcept主要是解決的問題是減少運(yùn)行時(shí)開銷. 運(yùn)行時(shí)開銷指的是, 編譯器需要為代碼生成一些額外的代碼用來包裹原始代碼,當(dāng)出現(xiàn)異常時(shí)可以拋出一些相關(guān)的堆棧stack unwinding錯(cuò)誤信息, 這里面包含,錯(cuò)誤位置, 錯(cuò)誤原因, 調(diào)用順序和層級路徑等信息.
當(dāng)使用noexcept聲明一個(gè)函數(shù)不會(huì)拋出異常候, 編譯器就不會(huì)去生成這些額外的代碼, 直接的減小的生成文件的大小, 間接的優(yōu)化了程序運(yùn)行效率.
?
noexcept 標(biāo)識(shí)符
noexcept 標(biāo)識(shí)符有幾種寫法: noexcept、noexcept(true)、noexcept(false)、noexcept(expression)、throw() .
其中 noexcept 默認(rèn)表示 noexcept(true).
當(dāng) noexcept 是 true 時(shí)表示函數(shù)不會(huì)拋出異常,
當(dāng) noexcept 是 false 時(shí)表示函數(shù)可能會(huì)拋出異常.
throw()表示函數(shù)可能會(huì)拋出異常, 不建議使用該寫法, 應(yīng)該使用 noexcept(false), 因?yàn)?C++20 放棄這種寫法.
// noexcept 標(biāo)識(shí)符
// noexcept 相當(dāng)于 noexcept(true)
// 聲明noexcept(true)之后, 將表示這個(gè)是不會(huì)報(bào)錯(cuò)的.
// 如果報(bào)錯(cuò)的話, 進(jìn)程直接結(jié)束, 不會(huì)拋出異常信息.
void example() noexcept {
cout << "hello called" << endl;
}
?
noexcept 函數(shù)
noexcept 函數(shù)用來檢查一個(gè)函數(shù)是否聲明了 noexcept, 如果聲明了noexcept(true)則返回true, 如果聲明了noexcept(false)則返回false.
#include <iostream>
using std::cout;
using std::endl;
using std::boolalpha;
// noexcept 標(biāo)識(shí)符
void foo() noexcept(true) {
throw 4;
}
// noexcept 標(biāo)識(shí)符
void bar() noexcept(false) {
throw 4;
}
int main(void) {
// noexcept 函數(shù)
cout << boolalpha << noexcept(foo()) << endl; // true
cout << boolalpha << noexcept(bar()) << endl; // false
return 0;
}
noexcept 函數(shù) 還可以在常規(guī)函數(shù)中配合 noexcept(expression) 標(biāo)識(shí)符 共同完成對其他函數(shù)是否聲明了 noexcept 的檢查.
#include <iostream>
using std::cout;
using std::endl;
using std::boolalpha;
struct foo {
int a;
void getFoo() noexcept(true) {
cout << "foo.getFoo called" << endl;
}
void getBar() noexcept(false) {
cout << "foo.getBar called" << endl;
}
};
template<typename T>
void example_true(T t) noexcept(noexcept(t.getFoo())) {
cout << "example called" << endl;
}
template<typename T>
void example_false(T t) noexcept(noexcept(t.getBar())) {
cout << "example called" << endl;
}
int main(void) {
foo x{};
cout << boolalpha << noexcept(example_true(x)) << endl; // true
cout << boolalpha << noexcept(example_false(x)) << endl; // false
return 0;
}
參考
C++標(biāo)準(zhǔn)庫 第二版 侯捷翻 第三章 第25頁
noexcept operator
noexcept specifier