使用新的C++ 11標準,我應該何時使用關鍵字constexpr
關鍵字inline
? constexpr
關鍵字是否提供了比inline
更多的優化,還是僅僅聲稱必須在編譯時計算?inline vs. constexpr?
爲什麼constexpr
在呼叫不固定的某些情況下在GCC上工作,例如在非constexpr
變量上調用foo(x)
?這是GCC中的錯誤還是它實際上是標準的一部分?
使用新的C++ 11標準,我應該何時使用關鍵字constexpr
關鍵字inline
? constexpr
關鍵字是否提供了比inline
更多的優化,還是僅僅聲稱必須在編譯時計算?inline vs. constexpr?
爲什麼constexpr
在呼叫不固定的某些情況下在GCC上工作,例如在非constexpr
變量上調用foo(x)
?這是GCC中的錯誤還是它實際上是標準的一部分?
斷言在編譯時可以計算出一些東西是是一種非常強大的優化。
內聯只是通過將函數體複製/粘貼到調用站點來刪除函數調用。函數體仍然需要執行,你只需要保存函數調用的開銷。
但是,如果您在編譯時對相同的代碼進行評估,那麼在運行時它是免費。
但是inline
和constexpr
都不是主要是關於優化。 inline
的主要目的是抑制一個定義規則,以便可以在頭文件中定義函數(這對模板有用,而且順便也使內聯優化更容易)
而constexpr
是因爲它在元編程中很有用,順便說一句,它可以幫助編譯器更好地優化代碼,將更多的計算轉移到編譯時。
引述維基百科:
的C++ 0x將介紹關鍵字constexpr,其允許用戶 保證的功能或對象的構造是一個編譯時 常數。
標記函數內聯,如果他們超短。如果編譯時需要結果,則標記函數爲constexpr。 (模板參數或數組大小)。如果需要,我相信一個函數可以是兩個。
可以使用 非constexpr參數調用常量表達式函數或構造函數。正如一個constexpr整數文字可以被分配給一個非constexpr變量的 ,一個constexpr函數 也可以用非constexpr參數調用,並且結果存儲在 非constexpr變量中。當表達式的所有成員都是 constexpr時,關鍵字只允許編譯時恆定性的可能性 。
因此,海灣合作委員會在這不是不正確的。
雖然inline
對編譯器說「這個函數在這個翻譯單元的某個地方使用,並沒有公開給其他目標文件」,但編譯器很可能會將函數主體插入到調用者中。 constexpr
函數對編譯器說:「這個函數沒有副作用,也不依賴於除參數本身之外的前提條件。「
constexpr
變量只是說」這個變量不會改變,它的數據可以包含在代碼中「但是它會影響你在一個靜態或非靜態函數中定義一個constexpr變量,例如,如果一個constexpr
陣列是非靜態,GCC只是使用硬編碼mov
-instructions將數據移動到堆棧,而只是static constexpr
存儲在.text
-section的數據。
分配給一個變量Lambda表達式,而不捕獲可能比捕獲constexpr其他,因爲沒有他們不需要記憶來保存捕捉,並且他們的工作像一個空載的類,超載operator()
(但它們甚至可以被轉換爲普通函數p帶有簡單的一元加號:+[]{}
)。
'inline'並不意味着內部鏈接,因爲您似乎在第一段中說過 –
根據[這個問題](http://stackoverflow.com/q/7065200/636019),當'constexpr'函數沒有用在需要常量表達式的上下文中時,編譯器沒有義務計算表達式在編譯時。 – ildjarn
但它仍指定計算*可以在編譯時執行。與'inline'一樣,它並不是真正的優化,但它可以提供編譯器可以用來優化的其他信息。 – jalf
對,我只是在挑剔使用「must」這個詞。 : - ] – ildjarn