【问题标题】:C++20. is_constant_evaluated() vs if constexpr [duplicate]C++20。 is_constant_evaluate() 与 if constexpr [重复]
【发布时间】:2019-12-23 15:18:15
【问题描述】:

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

【问题讨论】:

  • 你问为什么这里不能用if constexpr代替if
  • 是的。这正是我想要理解的
  • @rudolfninja:你认为这种情况在做什么?在您看来,等效的 if constexpr 条件会是什么样子?

标签: c++ c++20


【解决方案1】:

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

但是,if constexpr 的条件必须是一个常量表达式,无论它恰好在哪个函数中。因此,在if constexpr 的条件内执行is_constant_evaluated() 将始终产量true

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

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

【讨论】:

    【解决方案2】:

    std::is_constant_evaluated 的全部目的是能够在 if 语句中在运行时和编译时之间进行调度。

    如果您要使用if constexpr,那么您已经在一个常量表达式中并且条件将始终为真。

    相反,您使用常规的ifif 您在一个常量表达式中,您将在编译时获得 if 部分,如果不是,您将在运行时获得 else 部分。

    【讨论】:

      【解决方案3】:

      cppreference 已经回答了你的问题:

      当直接用作static_assert声明或constexpr if语句的条件时,std::is_constant_evaluated()总是返回true

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-11-26
        • 2022-01-10
        • 1970-01-01
        • 2020-11-02
        • 1970-01-01
        • 2017-09-12
        • 1970-01-01
        相关资源
        最近更新 更多