前几天我问了由标准编译器来决定是否,计算在编译时constexpr功能。
什么时候一个constexpr功能得到在编译时评价?
事实证明,一个constexpr仅在编译时评估,如果所有参数是恒定的表达式和要分配它是变量是恒定的表达。
template<typename base_t, typename expo_t>
constexpr base_t POW(base_t base, expo_t expo)
{
return (expo != 0 )? base * POW(base, expo -1) : 1;
}
template<typename T>
void foobar(T val)
{
std::cout << val << std::endl;
}
int main(int argc, char** argv)
{
foobar(POW((unsigned long long)2, 63));
return 0;
}
如果我被告知是真的,此代码示例是非常impratical,因为foobar的不采取constexpr(你不能使用consexpr的参数出于某种原因),POW被运行时进行评估,即使它本来可能在编译时计算它。 为迫使编译时的评价会是这样显而易见的解决方案:
auto expr = POW((unsigned long long)2, 63);
foobar(expr);
然而,这迫使我使用额外的代码行,这不应该是必要的我要确保在编译时一个constexpr被评估的每个时间。 为了使这个更方便一点,我想出了以下可疑宏:
#define FORCE_CT_EVAL(func) [](){constexpr auto ___expr = func; return std::move(___expr);}()
foobar(FORCE_CT_EVAL(POW((unsigned long long)2, 63)));
尽管它只是罚款的事实,我觉得好像有什么东西是不正确的了。 是否创建一个匿名拉姆达影响性能? 是否通过右值引用返回实际上表达移到函数参数? 怎样的std ::举动冲击性能? 对此有一个更好的班轮解决方案?