從C++11開始,咱們能看到不少代碼當中都有關鍵字noexcept。好比下面就是std::initializer_list
constexpr initializer_list() noexcept : _M_array(0), _M_len(0) { }
該關鍵字告訴編譯器,函數中不會發生異常,這有利於編譯器對程序作更多的優化。
若是在運行時,noexecpt函數向外拋出了異常(若是函數內部捕捉了異常並完成處理,這種狀況不算拋出異常),程序會直接終止,調用std::terminate()函數,該函數內部會調用std::abort()終止程序。優化
C++中的異常處理是在運行時而不是編譯時檢測的。爲了實現運行時檢測,編譯器建立額外的代碼,然而這會妨礙程序優化。
在實踐中,通常兩種異常拋出方式是經常使用的:this
後面這一種方式中在以往的C++版本中經常使用throw()表示,在C++ 11中已經被noexcept代替。code
void swap(Type& x, Type& y) throw() //C++11以前 { x.swap(y); } void swap(Type& x, Type& y) noexcept //C++11 { x.swap(y); }
在第2節中單獨使用noexcept,表示其所限定的swap函數絕對不發生異常。然而,使用方式能夠更加靈活,代表在必定條件下不發生異常。ci
void swap(Type& x, Type& y) noexcept(noexcept(x.swap(y))) //C++11 { x.swap(y); }
它表示,若是操做x.swap(y)不發生異常,那麼函數swap(Type& x, Type& y)必定不發生異常。編譯器
一個更好的示例是std::pair中的移動分配函數(move assignment),它代表,若是類型T1和T2的移動分配(move assign)過程當中不發生異常,那麼該移動構造函數就不會發生異常。it
pair& operator=(pair&& __p) noexcept(__and_<is_nothrow_move_assignable<_T1>, is_nothrow_move_assignable<_T2>>::value) { first = std::forward<first_type>(__p.first); second = std::forward<second_type>(__p.second); return *this; }
使用noexcept代表函數或操做不會發生異常,會給編譯器更大的優化空間。然而,並非加上noexcept就能提升效率,步子邁大了也容易扯着蛋。
如下情形鼓勵使用noexcept:io
struct X { ~X() { }; }; int main() { X x; // This will not fire even in GCC 4.7.2 if the destructor is // explicitly marked as noexcept(true) static_assert(noexcept(x.~X()), "Ouch!"); }
最後強調一句,在不是以上狀況或者沒把握的狀況下,不要輕易使用noexception。編譯