C++学习笔记 52 constexpr
constexpr
constexpr是 C++ 中用于声明编译时常量表达式的关键字,它要求变量、函数或构造函数的计算在编译时完成,而非运行时,从而提升程序性能。
基本概念与核心特性
constexpr 的核心是强制编译时计算,适用于变量、函数和类构造函数:
1. 变量声明:必须用常量表达式初始化,且类型为字面类型(如 int、float),否则编译报错。例如:
constexpr int x = 42; // 正确:编译时初始化
constexpr int y = j + 1; // 错误:j 非编译时常量
2. 函数要求
- 参数和返回值必须是字面类型。
- 函数体仅允许编译时可计算的操作(如 if、switch,但无 try 或 goto)。
- 递归在 C++14 后允许,虚函数在 C++20 后支持。
3. 优势:减少运行时开销,例如数组大小、模板参数等场景可直接用编译结果,避免重复计算。
与 const 的关键区别
constexpr 和 const 都表示常量,但核心差异在计算时机:
1. 初始化时机:
const:值可在运行时初始化(如 const int a = getValue();)。
constexpr:必须编译时初始化,值需为常量表达式。
2. 适用场景:
const:通用只读变量(如 const int PI = 3.14;)。
constexpr:需编译时计算的场景(如数组大小 constexpr int size = 10; int arr[size];)。
3. 性能影响:constexpr 通过编译时计算消除运行时开销,而 const 仅保证值不可变。
实际应用与编译器支持
1. 代码示例:
- 编译时计算阶乘:
constexpr int fac(int n) { return n <= 1 ? 1 : n * fac(n - 1); }
static_assert(fac(5) == 120); // 编译时验证
- C++23 扩展:std::bitset 和 std::unique_ptr 支持 constexpr,例如:
constexpr std::bitset<8> bits(42); // 编译时初始化
2. 编译器支持:
C++11:基础支持,仅限简单表达式。
C++14:允许递归、局部变量和更多控制结构。
C++17:支持 if constexpr 和 constexpr lambda。
C++23:扩展至 std::bitset、std::unique_ptr 等库。

浙公网安备 33010602011771号