第7.4章: if consteval

English

概述

if consteval 检查当前这次函数调用是否正在常量表达式 上下文中求值。它允许函数在编译期执行与运行时执行 表现出不同的行为。

与依赖常量表达式值的 if constexpr 不同, if consteval 取决于函数如何被求值。

1. 基础示例

当函数在编译期求值时,会选中 if consteval 分支。在运行时求值时,则选中 else 分支。


#include <fast_io.h>

constexpr int compute(int x)
{
    using namespace ::fast_io::iomnp;

    if consteval
    {
        print("computed at compile time\n");
        return x * 2;
    }
    else
    {
        print("computed at runtime\n");
        return x + 2;
    }
}

编译器根据求值上下文选择分支。

2. 强制编译期求值

constexpr 变量会强制其初始化器在编译期求值。 这意味着会选中 if consteval 分支。


constexpr int a = compute(10);  // compile-time evaluation
int b = compute(10);            // runtime evaluation

第一次调用会打印“computed at compile time”,第二次会打印 “computed at runtime”。

3. 为什么这很有用

当函数必须做到以下事情时,if consteval 很有用:

例如,当函数在编译期求值时,你可能想禁止某些操作。


#include <fast_io.h>

constexpr int safe_divide(int a, int b)
{
    using namespace ::fast_io::iomnp;

    if consteval
    {
        if(b == 0)
            print("error: division by zero in constant expression\n");
    }

    return a / b;
}

这允许进行编译期检查,而不会影响运行时行为。

4. 与 if constexpr 的区别

if constexpr 取决于一个常量表达式的值:


if constexpr(flag) { ... }

if consteval 取决于求值上下文:


if consteval { ... }

它们解决不同的问题:

要点