有没有办法在编译阶段和运行时实现constexpr
函数的不同行为?
考虑以下示例(使用D: static if
中的理论特征):
constexpr int pow( int base , int exp ) noexcept
{
static if( std::evaluated_during_translation() ) {
auto result = 1;
for( int i = 0 ; i < exp ; i++ )
result *= base;
return result;
} else { // std::evaluated_during_runtime()
return std::pow( base , exp );
}
}
如果没有,有没有办法将constexpr
限制为仅编译时间?
答案 0 :(得分:6)
答案 1 :(得分:3)
在C ++ 20之前,这是不可能的。 C ++ 20然后添加了std::is_constant_evaluated
,它恰好适合此用例:
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);
}
}
请注意,if
语句本身不是不是 constexpr
。如果是这样,则整个else臂将从函数中删除,并且无论在编译时还是在运行时,它将始终运行if臂。使用普通的if语句,您基本上可以获得两个功能。在编译时运行的一个:
constexpr int pow(int base, int exp) noexcept
{
auto result = 1;
for (int i = 0; i < exp; i++)
result *= base;
return result;
}
并在运行时编译运行:
constexpr int pow(int base, int exp) noexcept
{
return std::pow(base, exp);
}
编译器可以安全地删除if臂,因为它可以证明它在运行时不可访问。很整齐。