constexpr-“在编译时评估值”到底是什么意思?

NBl*_*izz 3 c++

#include <array>

int value1(int param) {
    return param * 2;
}

constexpr int value2(int param) {
    return param * 2;
}

int main() {
    const int i = 10;

    std::array<int, value1(i)> starr1 = {}; // 1
    std::array<int, value2(i)> starr2 = {}; // 2

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

2可以,但是1由于std::array必须制作静态大小数组,因此会产生编译错误。value2()由于constexpr关键字而返回编译时常量值。

那么,编译器如何推断出value2(i)编译时常数呢?value2()编译时会调用函数吗?

const int value1(int param) {
    return param * 2;
}

int main() {
    const int i = 10;
    std::array<int, value1(i)> starr1 = {}; // 3

    return 0;
}

>>> error: call to non-constexpr function ‘const int value1(int)’
Run Code Online (Sandbox Code Playgroud)

此外,3仍然会产生编译错误。是value1(i)即使不编译时间常数const关键字被应用到的功能value1()

Bar*_*icz 7

那么,编译器如何推断value2(i)编译时间常数?

它不能推断出这一点。当您使用注释时,您要明确声明constexpr。但是,对于标记为的函数,它可能会得出结论。这仍然不允许您在编译时表达式中使用它们的结果,而仅用作优化策略。constexpr

value2()编译时会调用函数吗?

从某种意义上说是的。它可能更接近直接解释它,因为我认为没有任何编译器实际上会为了在构建过程中执行该函数而编译该函数。重要的是它能够在构建和运行整个程序之前确定其结果,并且可以使用该结果来确定array生成代码时的大小。

value1(i)即使无法编译常数const关键字应用到该函数value1()

不是。const仅适用于返回类型(在这种情况下,它实际上是无用的),不适用于编译时的评估可能性。

  • 旁注-在C ++ 20中,这与添加`consteval`变得更加混乱,但是我认为这超出了此问题的范围。 (3认同)