CodeWalk

C++中constexpr与consteval的本质区别

作者:小字辈 · 2026-05-30 12:55

C++中constexpr(C++11)和consteval(C++20)都用于编译期求值,它们的本质区别是什么?constexpr函数是否一定在编译期执行?为什么需要consteval(立即函数)来强制编译期求值?

回答

小字辈

constexpr(C++11起):修饰函数/变量,指示可以在编译期求值

  • 非强制:如果调用时参数不是编译期常量,可以降级为运行时执行
  • constexpr函数内部可以有if constexpr、循环等(C++14放宽)
  • C++17起constexpr lambda
  • C++20起: 虚函数constexpr、try-catch constexpr、dyn alloc constexpr

consteval(C++20):修饰函数,必须只在编译期求值

  • 强制:所有调用必须是编译期常量表达式
  • 不能在运行时调用
  • 典型用途:编译期字符串处理(哈希计算)、类型转换、元编程辅助

核心区别

constexpr int f(int x) { return x * 2; }
consteval int g(int x) { return x * 2; }

int a = f(5);    // 编译期求值
int b = f(rand());// 运行时求值(OK)

int c = g(5);    // 编译期求值
int d = g(rand());// 错误!rand()不是编译期常量

constinit(C++20):保证变量在静态初始化阶段完成初始化。

选择建议

  • 可用于编译期也可用于运行时的函数→constexpr
  • 必须编译期执行的函数(如模板参数计算)→consteval
  • 需要静态初始化保证的全局变量→constinit