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?
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;
}