constexpr与const在C++中的区别是什么?完整指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:C++ 中常量的永恒之战

\n\n

如果你曾经写过 C++(或者只是刚开始学习它),你肯定遇到过 const。这个神奇的前缀承诺变量的值不会改变。但随后 C++11 带来了 constexpr。混乱就此开始。

\n\n

在 Stack Overflow 上,"constexpr 和 const 有什么区别?" 这个问题已经获得了数十万的浏览量。各种水平的程序员都会混淆这两个概念,将它们当作同义词使用。但这是一个大错误!

\n\n

在本教程中,我们将一劳永逸地弄清楚 C++ 中 constexpr 和 const 的区别。你将了解到:

\n
    \n
  • 什么是编译时常量和运行时常量。
  • \n
  • 为什么 const 并不总是与性能有关。
  • \n
  • constexpr 如何将 C++ 转变为一种现代且安全的语言。
  • \n
  • 何时使用这些构造。
  • \n
\n\n

让我们开始吧!🚀

\n\n

第 1 章:const:一个承诺,而非保证

\n\n

让我们从基础开始。C++ 中的 const 是一个类型限定符,它告诉编译器:“嘿,这个值在初始化后不能被改变。” 听起来很简单,但这里有一个陷阱。

\n\n

示例 1:const 的使用

\n\n
#include <iostream>\n\nint main() {\n    const int x = 42;  // 承诺:x 不会改变\n    // x = 100;        // 编译错误 — 很好!\n    \n    std::cout << x;   // 将输出 42\n    return 0;\n}
\n\n

一切看起来都不错。但是如果一个 const 变量的值是在运行时才计算出来的呢?

\n\n

示例 2:在运行时计算的 const

\n\n
#include <iostream>\n\nint get_value() {\n    return 42;  // 函数返回一个值\n}\n\nint main() {\n    const int y = get_value();  // 仍然是 const 吗?\n    // 但是 y 的值只有在运行时才知道!\n    \n    // 让我们尝试在数组中使用它:\n    // int arr[y];  // 错误!y 不是编译时常量!\n    \n    return 0;\n}
\n\n

看,这就是主要陷阱!const 保护变量不被修改,但不能保证其值在编译时已知。如果值来自函数,它只在程序运行时才被计算出来。

\n\n

关键要点: const 是关于不可变性的约定,而不是关于编译时可计算性的约定。

\n\n

第 2 章:constexpr:存在于代码中的常量

\n\n

这就是 constexpr 登场的时刻。这个说明符出现在 C++11 中,并从根本上改变了对常量的处理方法。constexpr 意思是:“这个值必须在编译时计算出来。” 或者,至少,它能够被计算出来。

\n\n

示例 3:constexpr 变量

\n\n
#include <iostream>\n\nint main() {\n    constexpr int z = 42;  // 保证:值在编译时已知\n    \n    int arr[z];  // 有效!z 是一个编译时常量\n    \n    std::cout << sizeof(arr) / sizeof(arr[0]);  // 将输出 42\n    return 0;\n}
\n\n

区别很明显:constexpr 允许在编译器需要知道确切值的地方使用变量——例如,用于数组大小或模板参数。

\n\n

示例 4:constexpr 函数

\n\n

但最有趣的部分是函数。constexpr 可以应用于函数,这样如果所有参数也都是编译时常量,它们就可以在编译时进行计算。

\n\n
#include <iostream>\n\nconstexpr int square(int x) {\n    return x * x;\n}\n\nint main() {\n    constexpr int result = square(5);  // 在编译时计算!\n    int arr[result];                   // 有效\n    \n    std::cout << result;  // 25\n    \n    int runtime_value =                

博客

书籍推荐