C++中constexpr的用法

193 阅读2分钟

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++ 标准的发展而不断扩展,可能还有一些边缘用法未被涵盖。但这些是最常见和最实用的场景。