2012-09-09 89 views
7

考慮下面的代碼:爲什麼constexpr使用模板?

template<typename T> 
constexpr inline T fma(T a, T b, T c) 
{ 
    return a * b + c; 
} 

這編譯就好了。但爲什麼呢?理論上,constexpr函數只能調用其他constexpr函數。但是,不能保證運營商將具有協同功能。舉例來說,假設我有一些類型有以下接口:

運算符+和* constexpr。如果我寫了下面的代碼:

fma(someType(), someType(), someType()); 

應該編譯失敗,因爲constexpr函數是調用非constexpr功能。但它編譯得很好。爲什麼是這樣?

我正在使用MinGW的G ++編譯器和-std = C++ 0x選項。

+0

對於一個很明顯的例子,它不能優化所有的東西,當輸入三個參數時,它會用GCC 4.7.1進行編譯,並顯示結果:http://ideone.com/aBRPU – chris

+0

試試這個: 'constexpr someType dummy = fma(someType(),someType(),someType());';) – mfontanini

+0

哦,我剛剛在標準中發現'constexpr'函數是隱式內聯的,如果這樣可以節省空間。 – chris

回答

5

如果使用非常量表達式作爲其參數調用constexpr函數,則該函數將在運行時執行。

如果你這樣做:

constexpr someType dummy = fma(someType(), someType(), someType()); 

它會失敗,因爲你正迫使結果存儲在一個constexpr類型。這不能在編譯時完成,因此會出現編譯錯誤。

注意,這想如果你同時提供了一個constexpr構造和constexproperator+/*someType工作。

0

由於模板大多在使用時檢查錯誤,所以只有當您將它與非constexpr運算符的類型一起使用時,它將會出錯。

5

從C++ 11標準的第7.1.5.6:

If the instantiated template specialization of a constexpr function template or member function of a class 
template would fail to satisfy the requirements for a constexpr function or constexpr constructor, that 
specialization is not a constexpr function or constexpr constructor. [ Note: If the function is a member 
function it will still be const as described below. — end note ] If no specialization of the template would 
yield a constexpr function or constexpr constructor, the program is ill-formed; no diagnostic required. 

這意味着,如果它與模板參數,這使得它不能被實例化一個constexpr函數模板降低到非constexpr功能一個有效的constexpr函數。

如果它不是一個有效的constexpr函數,無論你給了它什麼樣的模板參數,那麼編譯器可能會抱怨,但它並不是必須的。

相關問題