C++23将引入if consteval
。它将用于哪些场景,它与constexpr if
有何不同?
if consteval
可以检测一个constexpr
函数在常量表达式上下文中被调用的情况。该提案说明了它被引入的动机,用于意图从constexpr
函数中调用consteval
函数的情况。为了理解这意味着什么,我们考虑以下示例。
假设我们有一个consteval
函数f
:
consteval int f( int i )
{ ... }
f
只能在常量表达式中调用。另一方面,constexpr
函数g
可以在常量表达式或运行时调用,这取决于是否在编译时已知g
的参数。
如果在编译时已知g
的参数,则可以按以下方式从g
中调用f
。
constexpr int g( int i )
{
if consteval { //1
return f( i );
}
else {
return fallback();
}
}
在代码中,如果在常量表达式中调用函数g
,则位于//1
的if consteval
将被触发。
请注意,//1
处必须没有条件语句。此外,if consteval
后面的花括号是强制性的。
C++20引入了is_constant_evaluated
以检测函数调用是否发生在常量求值上下文中。在我们的例子中使用is_constant_evaluated
会导致一个微妙的错误。即通过将//1
替换为if constexpr (std::is_constant_evaluated()) {
,结果is_constant_evaluated
总是返回true
。
is_constant_evaluated
并不提供有关g()
整个函数体的信息,而是提供了if constexpr
控制表达式的信息。 - Ben Voigtif constexpr (is_constant_evaluated())
有问题(虽然它确实有问题,但编译器会发出警告,所以无所谓),而是即使使用if (is_constant_evaluated())
,你也不能在那里调用f(i)
。 - Barryis_constant_evaluated()
喜欢constexpr int x = f(5);
但不喜欢int x = f(5);
。 - klaus triendl