Search code examples
c++constexprconstevalc++23

What is if consteval needed for?


C++23 is going to introduce if consteval. Where is this going to be used and how does it differ from constexpr if?


Solution

  • 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.