How to obtain a constant expression when std::is_constant_evaluated?

Viewed 182

Let's start with the example (godbolt):

constexpr int len(int v) {
    if (std::is_constant_evaluated()) {
        // static_assert(v > 0); // ERR: 'v' is not a constant expression
        return v;
    } else {
        return 0;
    }
}

using A = std::array<int, len(3)>;

The problem is, that the static_assert won't compile (gcc / clang latest 10.x releases). Apparently, v isn't realized to be constexpr when std::is_constant_evaluated returns true. But clearly, by the use of len, it actually is.

Question: Is it possible to use a variable as constexpr if and only if std::is_constant_evaluated? If so, how?

2 Answers

Apparently, v isn't realized to be constexpr when std::is_constant_evaluated returns true. But clearly, by the use of len, it actually is.

No, it's actually not.

Function parameters are not constant expressions. It doesn't matter if you're in the middle of constant evaluation or not. You cannot use v as a constant expression in any context. static_assert requires a constant expression - this is why you cannot use v.

Question: Is it possible to use a variable as constexpr if and only if std::is_constant_evaluated? If so, how?

No, it is not. Because in order to use a variable as a constant expression, well, that's a template. And is_constant_evaluated can't conditionally make your function into a function template, that's just not how the compilation process can work. See P0992.

Not possible, but also unnecessary.

Instead of using a static_assert, you can throw something. Since you're in a constexpr context, it will give you a compile-time error.

Related