以下是cppreference中的示例:
constexpr double power(double b, int x)
{
if (std::is_constant_evaluated() && !(b == 0.0 && x < 0)) {
// A constant-evaluation context: Use a constexpr-friendly algorithm.
if (x == 0)
return 1.0;
double r = 1.0, p = x > 0 ? b : 1.0 / b;
auto u = unsigned(x > 0 ? x : -x);
while (u != 0) {
if (u & 1) r *= p;
u /= 2;
p *= p;
}
return r;
} else {
// Let the code generator figure it out.
return std::pow(b, double(x));
}
}
您会看到std::is_constant_evaluated()
。我的问题是为什么我们不能在此处使用if constexpr
来检查函数调用是否在常量求值的上下文中发生?
答案 0 :(得分:3)
is_constant_evaluated()
所提出的问题的名称中已明确说明:“此表达式是否在常量表达式求值范围内求值?”声明为constexpr
的函数可以或可以不作为常量表达式求值的一部分执行。因此,根据实现的调用方式,在这样的上下文中调用该函数可能会返回不同的值。
但是,if constexpr
的条件必须为一个常量表达式,而不管它恰好位于哪个函数中。因此,请在{{1}内执行is_constant_evaluated()
}的条件将始终产生if constexpr
。
您不能将true
用于is_constant_evaluated
的条件或任何其他明确的if constexpr
上下文。可以,但是它可能不会返回您真正感兴趣的结果。
此代码最终要做的工作是创建函数的两个版本:一个版本针对运行时执行进行了优化,而另一个版本针对编译时执行进行了优化。这就需要有一个条件来测试需要调用哪个版本。
答案 1 :(得分:1)
std::is_constant_evaluated
的全部目的是能够在if语句的运行时间和编译时间之间进行调度。
如果您要使用if constexpr
,那么您将已经处于常量表达式中,并且条件将始终为真。
相反,您使用正则if
和 if 来表示常量表达式,则在编译时将获得if部分,否则将在运行时获得else部分时间。
答案 2 :(得分:0)
cppreference已经回答了您的问题:
当直接用作
static_assert
声明或constexpr if
语句的条件时,std::is_constant_evaluated()
始终返回true
。