2014-06-20 90 views
2
#include <algorithm> 

struct S 
{ 
    static constexpr int X = 10; 
}; 

int main() 
{ 
    return std::min(S::X, 0); 
}; 

如果std::min需要一個const int&,編譯器很可能想有S::X還定義了某個地方,即S::X必須的存儲器中存在。力constexpr在編譯時進行評估

參見herehere

有沒有辦法force編譯器在編譯時評估我的constexpr

的原因是:

最初,我們在init優先靜態變量的初始化初出現了問題。有一些struct Type<int> { static int max; };,和一些全球static int x = Type<int>::max;,和一些其他早期代碼other_init使用,即x。當我們更新GCC時,突然我們在other_init中有x == 0

我們認爲我們可以通過使用constexpr來避免這個問題,因此它總會在編譯時評估它。

唯一的另一種方法是使用struct Type<int> { static constexpr int max(); };來代替,即讓它成爲函數。

+3

'constexpr'不能解決靜態初始化訂購Fiasco。 – chris

+0

你可以發佈給你的代碼嗎?我的意思是結構類型爲的那個。我有興趣看到它。 –

+0

@MarcoA .:你的意思是什麼代碼?它已經在那裏。讓'other_init'成爲__attribute __((構造函數))',然後'printf(「%i」,x);'。 – Albert

回答

3

constexpr在編譯時進行評估。你的問題是 由於事實std::min不是constexpr,所以 無論其輸入的,結果不是一個常量表達式 (特別是,如果初始化使用std::min靜態 壽命的變量,它是動態的初始化)。

最簡單的解決方案可能是定義你自己的min, 東西沿着線:

template <typename T> 
constexpr T staticMin(T a, T b) 
{ 
    return a > b ? b : a; 
} 

這將導致在編譯時全面評估,並 靜態初始化。

+2

我的問題不是關於'std :: min'。這只是一個例子。我不想複製所有的STL。另外,'std :: min'的結果不是一個常量表達式並不重要。我不想/需要/在編譯時要求評估'std :: min'。 – Albert

+0

那麼你的問題是什麼?在你的示例代碼中,'S :: X'是一個編譯時間常量,它在編譯時被評估。在編譯時不評估的是'std :: min',因爲'std :: min'不是'constexpr'。 –

+0

我不在乎'std :: min'在編譯時不被評估。'S :: X'不在編譯時進行評估,否則鏈接器不會抱怨丟失的符號。另請參閱我的鏈接問題,也許他們更清楚。 – Albert

0

對於被允許存在的模板值參數類型,你可以引入一個數據結構是這樣的:

template <typename T, T K> 
struct force 
{ 
    static constexpr T value = K; 
}; 

用法:

force<int, std::min(S::X, 0)>::value