C++關(guān)鍵字 noexcept

  1. 當(dāng) noexcept 是標(biāo)識(shí)符時(shí), 它的作用是在函數(shù)后面聲明一個(gè)函數(shù)是否會(huì)拋出異常.
  2. 當(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) noexcepttrue 時(shí)表示函數(shù)不會(huì)拋出異常,
當(dāng) noexceptfalse 時(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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容