最近我在我的constexpr函数中将一些if constexpr
修改为if
,发现它们仍然可以在编译时评估,并且运行良好。这里是一个最小的案例:
template<int N>
constexpr bool is_negative()
{
if constexpr (N >= 0) return false;
else return true;
}
int main()
{
constexpr bool v = is_negative<1>();
}
在上述情况中,N
必须在编译时已知,因为它是非类型模板参数,所以 if constexpr
在这里可以很好地工作。但是,它是一个 constexpr 函数,所以,如果我将 if constexpr
替换为 if
,据我所知,仍然 可能 可以获得返回值:
template<int N>
constexpr bool is_negative()
{
if (N >= 0) return false;
else return true;
}
int main()
{
constexpr bool v = is_negative<1>();
}
根据 cppref,constexpr
函数必须满足以下所有要求:不提及 if
。因此,如果我理解正确的话,即使所有相关变量在编译时已知(如上面的 is_negative
),包含 if
的 constexpr
函数是否在编译时评估是实现定义行为。
所以,我的结论是:
- c++17 之前,我们没有
if constexpr
,所以选择if
,这意味着不能保证我们的constexpr
函数在编译时被评估,所有取决于编译器实现 - c++17 之后,如果我们希望
constexpr
函数在编译时被评估,则首选if constexpr
。
以上都是我的个人想法,可能会遗漏/误解一些重要信息,请随时纠正。问题仍然未改变:if
和 if constexpr
,对于预期在编译时评估的 constexpr
函数,应该选择哪个。
参考文献: - 什么是可用于 constexpr 函数的内容? - "if constexpr()" 与 "if()" 的区别
is_negative()
和13
使条件13 >= 0
,编译器将解析为1(没有constexpr
)。现代编译器优化整个条件,但我不知道这是否是强制性的,如果是,从哪个标准版本开始。顺便说一句,if (N >= 0) return true; else return false;
:为什么不是return N >= 0;
?还是因为简化了[mcve]? - Scheff's Cat