跳转到内容

C++11 constexpr

来自代码酷
Admin留言 | 贡献2025年4月28日 (一) 21:27的版本 (Page creation by admin bot)

(差异) ←上一版本 | 已核准修订 (差异) | 最后版本 (差异) | 下一版本→ (差异)

模板:Note

C++11 constexpr[编辑 | 编辑源代码]

constexpr是C++11引入的关键字,用于声明编译时常量表达式(compile-time constant expression)。它允许在编译期计算表达式的值,从而优化性能并增强类型安全性。

核心概念[编辑 | 编辑源代码]

基本定义[编辑 | 编辑源代码]

constexpr可修饰:

  • 变量:声明该变量必须是编译期常量
  • 函数:声明该函数在给定编译期常量参数时可产生编译期常量结果

与const的区别[编辑 | 编辑源代码]

const vs constexpr
特性 const constexpr
初始化时机 运行期或编译期 必须在编译期确定
修饰函数 不能保证编译期求值 可编译期求值
数组大小 C++98中不可用 可用作数组维度

语法规范[编辑 | 编辑源代码]

变量声明[编辑 | 编辑源代码]

constexpr int max_size = 100;  // 正确:字面量初始化
constexpr double pi = 3.14159; // 正确:浮点字面量

函数声明[编辑 | 编辑源代码]

constexpr int factorial(int n) {
    return n <= 1 ? 1 : n * factorial(n - 1);
}

代码示例[编辑 | 编辑源代码]

基础示例[编辑 | 编辑源代码]

计算编译期阶乘:

#include <iostream>

constexpr int compute_factorial(int n) {
    return (n <= 1) ? 1 : (n * compute_factorial(n - 1));
}

int main() {
    constexpr int val = compute_factorial(5);  // 编译期计算
    int dynamic_val = compute_factorial(5);    // 运行期计算
    std::cout << "Compile-time: " << val 
              << "\nRuntime: " << dynamic_val;
}

模板:Output

进阶应用[编辑 | 编辑源代码]

编译期字符串哈希:

constexpr unsigned int hash_str(const char* s, int off = 0) {
    return !s[off] ? 5381 : (hash_str(s, off+1) * 33) ^ s[off];
}

int main() {
    constexpr auto hash = hash_str("hello");
    static_assert(hash == 2107146360, "Hash mismatch");
}

限制条件[编辑 | 编辑源代码]

constexpr函数在C++11中需满足:

  • 函数体必须只有单个return语句(递归除外)
  • 不能包含:
 * 循环语句
 * goto语句
 * 非字面类型的变量
 * 未初始化的变量

实际应用案例[编辑 | 编辑源代码]

案例1:固定尺寸数组[编辑 | 编辑源代码]

constexpr int get_array_size() { return 32; }

int main() {
    int arr[get_array_size()];  // 合法数组声明
}

案例2:模板元编程[编辑 | 编辑源代码]

结合模板实现编译期计算:

template<int N>
struct Factorial {
    static constexpr int value = N * Factorial<N-1>::value;
};

template<>
struct Factorial<0> {
    static constexpr int value = 1;
};

int main() {
    static_assert(Factorial<5>::value == 120, "");
}

版本演进[编辑 | 编辑源代码]

constexpr标准演进
标准 改进
C++11 基础功能
C++14 放宽函数限制(允许多语句、局部变量等)
C++17 支持if constexpr
C++20 支持虚函数、try-catch等

性能分析[编辑 | 编辑源代码]

pie title constexpr优化效果 "编译期计算" : 75 "运行期计算" : 25

数学公式示例(欧拉公式验证): eiπ+1=0在编译期验证:

#include <complex>
#include <iostream>

constexpr bool verify_euler() {
    using namespace std::complex_literals;
    constexpr std::complex<double> res = std::exp(1.0i * 3.1415926535);
    return (std::abs(res.real() + 1) < 1e-9) && 
           (std::abs(res.imag()) < 1e-9);
}

static_assert(verify_euler(), "Euler's formula failed");

最佳实践[编辑 | 编辑源代码]

  • 优先用constexpr替代宏常量
  • 对数学计算、查找表等使用constexpr
  • 注意C++11的限制条件
  • 利用static_assert进行编译期验证

页面模块:Message box/ambox.css没有内容。

参见[编辑 | 编辑源代码]