constexpr
是 C++11 引入的一个关键字,用于声明可以在编译时进行计算的常量表达式。随后的标准(C++14, C++17, C++20)对 constexpr
功能进行了扩展,增加了更多的使用场景和能力。下面是 constexpr
的主要用法及相应的示例代码。
1. 常量表达式变量
在 C++11 中,constexpr
可以用于声明变量,确保该变量的值在编译时是已知的。
constexpr int max_size = 100;
constexpr double pi = 3.14159;
2. 函数中的 constexpr
C++11 允许在函数中使用 constexpr
,但要求函数体必须足够简单(通常是单个 return 语句)。
constexpr int square(int x) {
return x * x;
}
3. C++14 中的扩展
在 C++14 中,constexpr
函数的限制被放宽,允许更复杂的逻辑,如局部变量和循环。
constexpr int factorial(int n) {
int result = 1;
for (int i = 2; i <= n; ++i) {
result *= i;
}
return result;
}
4. constexpr
构造函数和类
C++11 允许类构造函数为 constexpr
,使得可以在编译时创建和初始化类的对象。
class Point {
public:
constexpr Point(double xVal, double yVal) : x(xVal), y(yVal) {}
constexpr double getX() const { return x; }
constexpr double getY() const { return y; }
private:
double x, y;
};
constexpr Point origin(0, 0);
5. constexpr
if 语句(C++17)
C++17 引入了 constexpr if
,允许在编译时根据条件进行分支。
template<typename T>
constexpr auto get_value(T t) {
if constexpr (std::is_pointer<T>::value) {
return *t; // 解引用指针
} else {
return t; // 直接返回值
}
}
6. constexpr
lambda 表达式(C++17)
C++17 允许 lambda 表达式为 constexpr
。
constexpr auto square_lambda = [](int n) {
return n * n;
};
7. constexpr
的动态分配(C++20)
C++20 允许 constexpr
中使用动态内存分配。
constexpr auto create_array(int n) {
return std::to_array({1, 2, 3, 4, 5}); // C++20
}
以上是 constexpr
的主要用法。由于 constexpr
随着 C++ 标准的发展而不断扩展,可能还有一些边缘用法未被涵盖。但这些是最常见和最实用的场景。