標籤:

noexcept標識符為什麼不這樣設計?

當一個函數沒有被標識為noexcept的時候

是否不應該認為該函數一定就不是noexcept的

而是應該根據函數體是否會潛在拋出異常來決定該函數是否是noexcept

c++11~c++14的做法就是如果不標識noexcept 那就不是noexcept

導致我經常需要這麼寫

template &
auto max(T const a,T const b) noexcept(noexcept(a &> b ? a : b)) {
return a &> b ? a : b;
}

noexcept(max(0,0)); //true
noexcept(max(a,b)); //false(假設a,b類型為T T類型的operator&>或者拷貝構造不是noexcept的)

這簡直是多此一舉嘛!

我覺得讓不顯式標識noexcept的函數等價於noexcept(noexcept(函數體))就好了啊

這樣會有什麼問題么?

歸根結底問題不出在noexcept標識符

而是出在noexcept操作符的規則上

我覺得noexcept操作符的規則應該改成:當表達式中的所有函數都 顯式標識了noexcept或潛在不拋出異常就返回true

============================================================================

想到不妥之處了

潛在不拋異常這似乎只在表達式中所有函數的實現都是編譯期可見時才能在編譯期判斷這件事(而noexcept操作符又是一個編譯期常量)

對於編譯後的二進位來說

因為c++規範不管二進位規範

所以如果頭文件函數簽名中沒有顯式的noexcept

根本就沒有辦法判斷一個編譯的函數是否潛在不拋出異常

而且就算是二進位文件中確實包含了是否拋出異常的信息

這個也是得到鏈接時才能知道的

所以完全不可能在編譯期就得知


因為函數簽名不應該依賴與實現,而是要讓實現去遷就函數簽名。正確的做法當然是你先確定這個函數,到底是需要throw,還是需要noexcept,然後你才去實現它。如果你只是想讓編譯器替你推導的話,那你什麼都不管就好了。一個不會拋異常的函數,在開啟了優化之後,這個事實也會被發現的。除此之外,你讓noexcept如此精確,有什麼意義?


推薦閱讀:

C語言int型(2位元組)數據的值的範圍為什麼是-2^15~(2^15-1)?
C++域作用符在函數聲明和定義中的意義?
在 64 位平台開發時是否應盡量避免使用指針?
C++中為什麼派生類中只有基本類型時,delete一個指向派生類的基類指針時卻沒有內存泄漏?
c++在執行運行時多態時,為什麼需要借用rtti來判斷對象真實類型?

TAG:CC | C11 | C14 |