Is it possible, at compile time, to determine if a call to a function (a constexpr function mainly) is compile-time evaluated and than just make another version of that function (like what a template does) with a different return type than the original runtime evaluated version ? How ?
constexpr decltype(auto) F(int n)
{
if consteval
{
return (int)3;
}
else
{
return (char)'c';
}
}
int main() {
int n;
cin >> n;
cout << typeid(decltype(F(4))).name() << endl;
cout << typeid(decltype(F(n))).name() << endl;
return 0;
}
error (gcc 12.2) : "inconsistent deduction for auto return type: 'int' and then 'char'"
Using if constexpr doesn't give this error, because I think it just "deletes" a section of code (if it is false, the "if" section, otherwise the "else" section). But why doesn't if consteval do the same thing ?
Is there an other way to do this ?
No, it is not possible.
constevalif statements (besides their effect onconstevalfunction calls) are essentially equivalent to:The reason why
constexprif statements can influece return type deduction is that they turn the false branch into a discarded statement, making it as if you hadn't written that code at all.A
constevalif statement is simply not going to execute one of the two branches, just like a regular if statement.Possible Solution
With this solution, you have two separate functions, but you call them with the same name because they are overloads of each other. It is a bit more powerful than just using
if constevalinside a function though, because any call tofis going to be constant-evaluated if possible, even in cases where it's otherwise not required.