C++23 is going to introduce if consteval
. Where is this going to be used and how does it differ from constexpr if
?
The consteval specifier declares a function or function template to be an immediate function, that is, every potentially evaluated call (i.e. call out of an unevaluated context) to the function must (directly or indirectly) produce a compile time constant expression.
The keyword constexpr was introduced in C++11 and improved in C++14. It means constant expression. Like const , it can be applied to variables: A compiler error is raised when any code attempts to modify the value. Unlike const , constexpr can also be applied to functions and class constructors.
Apart from the obvious compile time evaluation of functions, consteval functions can be used where pre-processor macro like functions are used.
Summary consteval functions result in error when it cannot produce a compile time error, whereas is not true for a constexpr function. Prefer consteval when a guarantee is needed on compile time evaluation of a function. Prefer consteval functions over a pre-processor macro function.
The consteval specifier declares a function or function template to be an immediate function, that is, every potentially evaluated call (i.e. call out of an unevaluated context) to the function must (directly or indirectly) produce a compile time constant expression .
With C++20 we get two new keywords: consteval and constinit. consteval produces a function that is executed at compile-time and constinit guarantees that a variable is initialized at compile-time.
if consteval
detects if a constexpr
function is called in a constant expression context. The proposal motivates its introduction for the case where one intends to call a consteval
function from a constexpr
function. To understand what that means we consider the following example.
Let's assume we have a consteval
function f
:
consteval int f( int i )
{ ... }
f
can only be called in a constant expression. On the other hand a constexpr
function g
can be called either in a constant expression or at run time. That depends on if the arguments to g
are known at compile time or not.
Now, calling f
from g
if g
is called at compile time can be done as follows.
constexpr int g( int i )
{
if consteval { //1
return f( i );
}
else {
return fallback();
}
}
Here if consteval
in line //1
triggers if g
is called in a constant expression.
Note that there must be no condition in //1
. Also the braces after if consteval
are obligatory.
C++20 introduced is_constant_evaluated
for detecting whether a function call occurs within a constant-evaluated context. Using is_constant_evaluated
in our example leads to a subtle bug. I.e. exchanging //1
by if constexpr (std::is_constant_evaluated()) {
results in is_constant_evaluated
to always return true
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With