我一直在使用以下代码段来理解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
为什么编译时评估仅在我在此示例中尝试断言时才起作用?
注意:对于此示例,任何优化的分析似乎都没有意义,因为看起来编译器发现结果是恒定的,而不管循环中调用的函数是否给出了与上面最快的概要时间相似的时序。
答案 0 :(得分:3)
constexpr
不保证编译时评估,除非在static_assert
,模板参数或任何其他需要在编译时通过语言规则知道值的地方使用。
斐波纳契系列f(n) = f(n - 1) + f(n - 2), f(0) = f(1) = 1
就是一个很好的例子。在我的机器上使用gcc,对于n <= 10
,这个get在编译时被评估。对于任何其他参数,编译器被允许 - 实际上 - 确定它计算量太大并且默认为运行时评估。