“If consteval” is useful in the context of calling a consteval function from within a constexpr function.
A consteval function can only be invoked in a constant expression and hence is evaluated at compile-time. On the other hand, a constexpr function may be invoked in a constant expression or non-constant expression. If invoked in a constant expression, it will be evaluated at compile-time, else it is executed at run-time. Both are implicitly inline.
Because of the dual nature of a constexpr function (i.e., evaluated at compile-time or at run-time), it can be tricky to invoke a consteval function inside a constexpr function. Here is where the newly introduced C++23 construct “if consteval” offers help.
The following example shows how it can be used:
Let us try to understand the key parts of the code. bar() is a consteval function. foo() is a constexpr function. Inside this function, we wish to call bar() when it is safe to call it, otherwise we want some other code to be executed. Safe here means that foo() is executing in the context of a constant expression. This is where “if consteval” comes in handy. We can now wrap the call to bar() in a “if consteval” block.
Line 29 uses static_assert, which is a compile-time assertion, to check whether foo() works correctly. As you can infer, foo() is now evaluated at compile-time since “5” is a constant expression, and this enables the call to bar() wrapped inside the “if consteval” block.
Lines 30 and 31 define two constexpr variables using foo() and bar() respectively. The call to bar() is once again in the context of a constant expression and hence is valid.
In contrast, line 35 invokes foo() in a non-constant expression and hence, inside foo(), the call to bar() is bypassed.
Line 39 (commented out) calls bar() with a non-constant expression and hence is invalid.
When the program is executed, it generates the following output:
The output matches the expected program behaviour.
You can view the program in Compiler Explorer.
Have a nice weekend!
Recent Comments