Is there a way to achieve different behaviour of a constexpr
function in the compilation phase and at runtime?
Consider the following example (using a theor
No, there is no such way.
Sorry.
N3583 is a paper proposing changes to allow what you are asking for.
Prior to C++20, this wasn't possible. C++20 then added std::is_constant_evaluated which is exactly for this use case:
constexpr int pow(int base, int exp) noexcept
{
if (std::is_constant_evaluated())
{
auto result = 1;
for (int i = 0; i < exp; i++)
result *= base;
return result;
}
else
{
return std::pow(base, exp);
}
}
Note that the if
statement itself is not constexpr
. If it were, the whole else arm would be removed from the function and it would always run the if arm, no matter if at compile time or runtime. With a normal if statement, you basically get two functions. One that runs at compile time:
constexpr int pow(int base, int exp) noexcept
{
auto result = 1;
for (int i = 0; i < exp; i++)
result *= base;
return result;
}
and one that gets compiled an runs at runtime:
constexpr int pow(int base, int exp) noexcept
{
return std::pow(base, exp);
}
The compiler can safely remove the if arm because it can prove that it isn't reachable at runtime. Pretty neat.