C ++ 20。 is_constant_evaluated()与constexpr比较

时间:2019-12-23 15:18:15

标签: c++ c++20

以下是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来检查函数调用是否在常量求值的上下文中发生?

3 个答案:

答案 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