2

Here is example from 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));
}
}

As you can see std::is_constant_evaluated(). My question is why can't we use if constexpr here to check if the function call occurs within a constant-evaluated context?

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
rudolfninja
  • 467
  • 7
  • 24

3 Answers3

6

The question which is_constant_evaluated() is asking is exactly spelled out in its name: "is this expression being evaluated within constant expression evaluation?" A function declared constexpr may or may not be executed as part of constant expression evaluation. So calling that function within such a context may return different values depending on how the implementation calls it.

However, the condition of if constexpr must be a constant expression, regardless of what function it happens to be in. And therefore, executing is_constant_evaluated() within if constexpr's condition will always yield true.

You cannot use is_constant_evaluated with if constexpr's condition or any other explicitly constexpr context. Well, you can, but it probably won't return the result that you're actually interested in.

What this code is ultimately doing is creating two versions of the function: one which is optimized for runtime execution and the other which is optimized for compile-time execution. That requires having a condition that tests which version needs to be called.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
1

The whole purpose of std::is_constant_evaluated is to be able to dispatch between run time and compile time in your if statement.

If you were to use if constexpr, then you would already be in a constant expression and the condition will always be true.

Instead you use a regular if and if you are in a constant expression you'll get the if part at compile time and if not you'll get the else part at run time.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
0

cppreference already answers your question:

When directly used as the condition of static_assert declaration or constexpr if statement, std::is_constant_evaluated() always returns true.

Kane
  • 5,595
  • 1
  • 18
  • 27