2014-03-04 118 views
3

的constexpr函數編譯時評價我一直在玩下面的代碼片段來了解constexpr在調試模式

#include <stdlib.h> 

/////////////////// 
bool runtimeIsPalindrome(const char* s, int len) 
{ 
    if(len < 2) 
    return true; 
    else 
    return s[0] == s[len-1] && runtimeIsPalindrome(&s[1], len-2); 
} 

/////////////////// 
constexpr bool compileTimeIsPalindrome(const char* s, int len) 
{ 
    return len < 2 ? true : s[0] == s[len-1] && compileTimeIsPalindrome(&s[1], len-2); 
} 

/////////////////// 
int main() 
{ 
    constexpr char c[] = "helloworlddlrowolleh"; 
    for(size_t nn=0;nn<1e8; ++nn) { 
     // static_assert(compileTimeIsPalindrome(c, sizeof(c)-1), "Blah"); 
     // compileTimeIsPalindrome(c, sizeof(c)-1); 
     // runtimeIsPalindrome(c, sizeof(c)-1); 
    } 
} 

隨着runtimeIsPalindrome版本...

clear; g++ -std=c++11 plaindrome.cpp; time ./a.out 
real 0m8.333s 
user 0m8.322s 
sys  0m0.005s 

隨着compileTimeIsPalindrome版本...

clear; g++ -std=c++11 plaindrome.cpp; time ./a.out 
real 0m8.257s 
user 0m8.247s 
sys  0m0.004s 

...但與static_assert(compileTimeIsPalindrome版本其實我似乎看到一些編譯時間魔法......

clear; g++ -std=c++11 plaindrome.cpp; time ./a.out 
real 0m0.265s 
user 0m0.263s 
sys  0m0.001s 

爲什麼編譯時評估只在我嘗試使用這個例子中的斷言時才起作用?

注意:對於此示例,對任何優化進行的分析似乎毫無意義,因爲看起來編譯器發現結果是恆定的,與循環中調用的函數無關,給出了與上述最快配置文件時間類似的時序。

回答

3

constexpr不保證編譯時間評估,除非在static_assert,模板參數或在語言規則編譯時必須知道值的任何其他位置中使用。

斐波納契數列f(n) = f(n - 1) + f(n - 2), f(0) = f(1) = 1是一個很好的例子。在我的機器上使用gcc,對於n <= 10,這個get在編譯時進行評估。對於任何其他參數,編譯器被允許並確實確定它的計算量過大,並且默認爲運行時評估。

+1

啊,我錯過了這個答案http://stackoverflow.com/questions/14248235/when-does-a-constexpr-function-get-evaluated-at-compile-time/14248310#14248310」的關鍵點。 ......並且結果也用於一個常量表達式以及「 – learnvst