if consteval
if consteval
是 C++23 引入的新特性,该特性是关于immediate function 的,即consteval function。用于在编译时检查当前是否处于 立即函数上下文(即常量求值环境),并根据结果选择执行不同的代码路径。它是对 std::is_constant_evaluated()
的更直观替代,语法更简洁。
核心作用
解决的问题其实很简单,在C++20,consteval function 可以调用constexpr function,而反过来却不行。
-
判断当前是否在 编译时求值(如
consteval
函数、常量表达式等)。 -
若在编译时求值,执行
if consteval
代码块;否则执行else
分支(如果有)
语法
if consteval
{// 编译时执行的代码
}
else
{// 运行时执行的代码(可选)
}
示例代码
示例 1:if consteval的好处之一
consteval auto bar(int m)
{return m * 6;}constexpr auto foo(int m) {return bar(m);}int main() {[[maybe_unused]] auto res = foo(42);std::cout << res << std::endl;return 0;}
以上代码无法编译通过,因为constexpr function 不是强保证执行于编译期,在其中自然无法
调用consteval function。但是,即便加上if std::is_constant_evaluated() 也无法编译成功。
constexpr auto foo(int m)
{if (std::is_constant_evaluated()) {return bar(m);}return 42;
}
这就存在问题了,P1938 通过if consteval修复了这个问题。在C++23,可以这样写:
constexpr auto foo(int m)
{if consteval {return bar(m);}return 42;
}
完整代码:
#include <iostream>consteval auto bar(int m)
{return m * 6;}constexpr auto foo(int m)
{if consteval {return bar(m);}return 42;
}int main() {[[maybe_unused]] auto res = foo(42);std::cout << res << std::endl;return 0;}
示例 2:编译时与运行时不同行为
#include <iostream>constexpr int calculate(int x)
{if consteval
{// 编译时:使用更精确的算法return x * x + 2;} else
{// 运行时:简化计算return x + 1;}
}int main()
{constexpr int a = calculate(5); // 编译时计算:5*5+2=27int b = calculate(5); // 运行时计算:5+1=6std::cout << a << " " << b; // 输出:27 6return 0;
}
示例 2:编译时断言与运行时错误
与 std::is_constant_evaluated()
的区别
特性 | if consteval | std::is_constant_evaluated() |
---|---|---|
引入版本 | C++23 | C++20 |
语法形式 | 直接条件分支 | 返回 bool 的函数调用 |
适用场景 | 需要明确分支的代码块 | 需要布尔判断的表达式(如返回值) |
是否支持 else | 是 | 需手动实现 |