Reputation:
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 ?
Upvotes: 0
Views: 136
Reputation: 39415
No, it is not possible. consteval
if statements (besides their effect on consteval
function calls) are essentially equivalent to:
if (std::is_constant_evaluated()) // if consteval
if (!std::is_constant_evaluated())) // if !consteval
The reason why constexpr
if 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 consteval
if statement is simply not going to execute one of the two branches, just like a regular if statement.
#include <concepts>
struct wrapper {
int x;
wrapper(int x) : x(x) {}
};
consteval int f(std::convertible_to<int> auto&&) {
return 1;
}
// Will lose in overload resolution to the function above
// because the conversion sequence is longer.
char f(wrapper) {
return char(0);
}
int main() {
return f(123);
}
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 consteval
inside a function though, because any call to f
is going to be constant-evaluated if possible, even in cases where it's otherwise not required.
Upvotes: 3