Search code examples
c++c++20consteval

Is it possible to call a consteval function with a non-const reference parameter?


If I understood the rules for immediate functions correctly, the following is a legal usage:

consteval void func(int& a) { /* Anything here... */ }

Is it possible to call this function? I could not find any way to do so as consteval forces that this has to be called in a compile time expression, but int& a forces it to be a runtime expression because of the missing const. Is there any other way that I am missing?


Solution

  • but int& a forces it to be a runtime expression because of the missing const

    No, that's a gross oversimplification and not how constant evaluation works. We can have moving parts (non-const qualified objects) as part of the evaluation. So long as they obey a strict set of rules that are checked when evaluating the constant expression. For example:

    consteval void func(int& a) { a = 2; }
    consteval int func2() { int b = 0; func(b); return b; }
    
    int arr[func2()];
    

    That's a pretty convoluted way of returning 2 for an array size, but it demonstrates the concept and one of the aforementioned rules. While doing constant evaluation, we introduced a helper variable b. We then proceeded to do something with it, modifying it, and return the result. That's the "evaluation" part.

    The "constant" bit is in the expression truly being evaluatble during translation, all of its "inputs" are compile time constant (vacuously). And any non-const objects we used only came into being while doing the evaluation, not living longer than until it is completed.