Brotcrunsher
Brotcrunsher

Reputation: 2254

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?

Upvotes: 2

Views: 501

Answers (2)

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.

Upvotes: 3

HolyBlackCat
HolyBlackCat

Reputation: 96906

  1. If int &a is unused, then it doesn't matter what you pass to it. The same applies to constexpr functions.

  2. If you read/write to int &a, then your function is only usable from some other consteval function. Example:

    consteval void func(int &x)
    {
        x++;
    }
    
    consteval int foo(int x)
    {
        func(x);
        return x;
    }
    
  3. If you merely take the address of int &a, then your function will work when given a reference to a global or static object.

Upvotes: 0

Related Questions