consteval
specifier
(since C++20)
| General topics | ||||||||||||||||
| Flow control | ||||||||||||||||
| Conditional execution statements | ||||||||||||||||
| Iteration statements (loops) | ||||||||||||||||
|
||||||||||||||||
| Jump statements | ||||||||||||||||
| Functions | ||||||||||||||||
| Function declaration | ||||||||||||||||
| Lambda function expression | ||||||||||||||||
inline
specifier
|
||||||||||||||||
| Dynamic exception specifications ( until C++17* ) | ||||||||||||||||
noexcept
specifier
(C++11)
|
||||||||||||||||
| Exceptions | ||||||||||||||||
| Namespaces | ||||||||||||||||
| Types | ||||||||||||||||
| Specifiers | ||||||||||||||||
|
||||||||||||||||
| Storage duration specifiers | ||||||||||||||||
| Initialization | ||||||||||||||||
| Expressions | ||||||||||||||||
| Alternative representations | ||||||||||||||||
| Literals | ||||||||||||||||
| Boolean - Integer - Floating-point | ||||||||||||||||
| Character - String - nullptr (C++11) | ||||||||||||||||
| User-defined (C++11) | ||||||||||||||||
| Utilities | ||||||||||||||||
| Attributes (C++11) | ||||||||||||||||
| Types | ||||||||||||||||
typedef
declaration
|
||||||||||||||||
| Type alias declaration (C++11) | ||||||||||||||||
| Casts | ||||||||||||||||
| Memory allocation | ||||||||||||||||
| Classes | ||||||||||||||||
| Class-specific function properties | ||||||||||||||||
|
||||||||||||||||
| Special member functions | ||||||||||||||||
|
||||||||||||||||
| Templates | ||||||||||||||||
| Miscellaneous | ||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-
-
consteval- 指定函数为 立即函数 ,即对该函数的每次调用都必须生成编译时常量
-
目录 |
说明
consteval
说明符用于声明函数或函数模板为
立即函数
,即每个对该函数的
潜在求值
调用必须(直接或间接)产生一个编译期
常量表达式
。
立即函数是一种
constexpr函数
,根据具体情况需满足其要求。与
constexpr
相同,
consteval
说明符隐含
inline
特性。但该说明符不得应用于析构函数、分配函数或释放函数。
声明为
consteval
的函数或函数模板不可同时指定
constexpr
,且该函数或函数模板的所有重声明也必须指定
consteval
。
对立即函数的潜在求值调用,若其最内层非块作用域不是某个立即函数的 函数形参作用域 或 consteval if 语句 的真分支 (C++23 起) ,则必须产生常量表达式;此类调用被称为 立即调用 。
consteval int sqr(int n) { return n*n; } constexpr int r = sqr(100); // 正确 int x = 100; int r2 = sqr(x); // 错误:调用无法产生常量 consteval int sqrsqr(int n) { return sqr(sqr(n)); // 此处不是常量表达式,但允许 } constexpr int dblsqr(int n) { return 2 * sqr(n); // 错误:外围函数不是 consteval // 且 sqr(n) 不是常量 }
一个 标识符表达式 若表示立即函数,则仅可出现在立即调用的子表达式内,或处于 立即函数上下文 中(即上文提及的、调用立即函数无需为常量表达式的语境)。可以获取立即函数的指针或引用,但不得脱离常量表达式求值范围:
consteval int f() { return 42; } consteval auto g() { return &f; } consteval int h(int (*p)() = g()) { return p(); } constexpr int r = h(); // 正确 constexpr auto e = g(); // 非法的:指向立即函数的指针不是常量表达式的合法结果 //
注释
| 功能测试宏 | 值 | 标准 | 功能特性 |
|---|---|---|---|
__cpp_consteval
|
201811L
|
(C++20) | 即时函数 |
202211L
|
(C++23)
(DR20) |
使 consteval 向上传播 |
关键词
示例
#include <iostream> // 如果输入在编译期已知,此函数可能在编译期求值 // 否则将在运行时执行 constexpr unsigned factorial(unsigned n) { return n < 2 ? 1 : n * factorial(n - 1); } // 使用 consteval 强制函数在编译期求值 consteval unsigned combination(unsigned m, unsigned n) { return factorial(n) / factorial(m) / factorial(n - m); } static_assert(factorial(6) == 720); static_assert(combination(4, 8) == 70); int main(int argc, const char*[]) { constexpr unsigned x{factorial(4)}; std::cout << x << '\n'; [[maybe_unused]] unsigned y = factorial(argc); // 正确 // unsigned z = combination(argc, 7); // 错误:'argc' 不是常量表达式 }
输出:
24
参见
constexpr
说明符
(C++11)
|
指定变量或函数的值可在编译时计算 |
constinit
说明符
(C++20)
|
断言变量具有静态初始化,即 零初始化 和 常量初始化 |
| 常量表达式 | 定义可在编译时求值的 表达式 |