C++20。is_constant_evaluate() 与 if constexpr

rud*_*nja 1 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));
}
}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的std::is_constant_evaluated()。我的问题是为什么我们不能if constexpr在这里使用来检查函数调用是否发生在常量评估的上下文中?

Nic*_*las 5

所问的问题is_constant_evaluated()在其名称中得到了明确说明:“这个表达式是否在常量表达式求值中求值?” 声明的函数constexpr可能会或可能不会作为常量表达式评估的一部分执行。因此,在这样的上下文中调用该函数可能会返回不同的值,具体取决于实现如何调用它。

然而,条件 ofif constexpr 必须是一个常量表达式,不管它碰巧在哪个函数中。因此,执行is_constant_evaluated()if constexpr条件将始终产生true

您不能使用is_constant_evaluatedwithif constexpr的条件或任何其他明确的constexpr上下文。好吧,你可以,但它可能不会返回你真正感兴趣的结果。

这段代码最终要做的是创建函数的两个版本:一个针对运行时执行进行了优化,另一个针对编译时执行进行了优化。这需要有一个条件来测试需要调用哪个版本。