Home > OS >  How to call an operator with constexpr without using temporary variables?
How to call an operator with constexpr without using temporary variables?

Time:04-10

The following sample code illustrates my problem.

constexpr int fact(int N) {
    return N ? N * fact(N - 1) : 1;
}
struct A {
    int d;
    constexpr A operator (const A& other) const { return A{ fact(d   other.d) }; }
    // overload of many other operators
};

int main() {
    int x;
    cin >> x;                       // run time argument

    constexpr A a{ 2 }, b{ 3 };
    A c{ x };

    A u = a   b   c;                // both   eval at run time
    //constexpr A v = a   b   c;    // doesn't compile because c is not constant
}

What I want to achieve is that the first operator is evaluated at compile time and the second operator is evaluated at run time.

It is of course possible to break it into

constexpr A tmp = a   b;
A u = tmp   c;

but in my case the whole point of overloading operators is to allow building more complicated formulas in a more intuitive way, so that would make the overloading pointless.

If I declare operator as consteval, then it again doesn't compile. And I cannot overload it twice.

Is there a solution?

CodePudding user response:

You can force the evaluation with (non-type) template parameter or consteval function.

constexpr int fact(int N) {
    return N ? N * fact(N - 1) : 1;
}
struct A {
    int d;
    constexpr A operator (const A& other) const { return A{ fact(d   other.d) }; }
};

consteval auto value(auto v){return v;}

A foo (int x) {

    constexpr A a{ 2 }, b{ 3 };
    A c{ x };

    A u = value(a b)   c;
    return u;
}

https://godbolt.org/z/ohf61vebv

CodePudding user response:

No, at least in gcc and with optimization, here you can see it evaluate at compile time. (the 120)

main:
        mov     eax, 1
        add     edi, 120
        je      .L4
.L3:
        imul    eax, edi
        sub     edi, 1
        jne     .L3
        ret
.L4:
        ret

*To be fair even without constexpr compiler would probably also optimize it.

  • Related