【发布时间】:2021-09-13 16:32:49
【问题描述】:
C++23 即将引入if consteval。这将在哪里使用,它与constexpr if 有何不同?
【问题讨论】:
标签: c++ constexpr consteval c++23
C++23 即将引入if consteval。这将在哪里使用,它与constexpr if 有何不同?
【问题讨论】:
标签: c++ constexpr consteval c++23
if consteval 检测是否在常量表达式上下文中调用了 constexpr 函数。 proposal 将其引入用于打算从 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 会导致一个微妙的错误。 IE。将//1 与if constexpr (std::is_constant_evaluated()) { 交换会导致is_constant_evaluated 始终返回true。
【讨论】:
is_constant_evaluated 没有给你g() 的整个主体的信息,而是if constexpr 的控制表达式?
if constexpr (is_constant_evaluated()) 是一个错误(它是,但编译器警告,所以嗯),但即使使用if (is_constant_evaluated()) 你也不能在那里调用f(i)。