我们可以在constexpr函数中省略const局部变量吗?

时间:2015-11-01 15:26:21

标签: c++ c++11 const c++14 constexpr

例如:

constexpr int g() { return 30; }    

constexpr int f()
{
    // Can we omit const?
    const int x = g();
    const int y = 10;

    return x + y;
}

是否有任何要点constexpr函数中使用const声明局部变量?

Aren的constexpr函数与const局部变量等效与没有const的人相比

换句话说,函数 constexpr对其局部变量强加(暗示)const吗?

4 个答案:

答案 0 :(得分:23)

在非const函数中将变量声明为constexpr的相同参数也适用于constexpr函数:

  • 声明变量const记录了它不会被改变的事实。在某些情况下,这可能有助于使函数更具可读性。
  • 声明变量const会影响重载解析,并可能会h(x)以不同的方式解析h,具体取决于xconst

当然,正好相反,如评论中所述:

即使在constexpr函数中,也可能会更改局部变量。如果这些变量随后被更改为const,则不再接受尝试更改它们。

答案 1 :(得分:16)

这个特定示例中,局部变量最好是constexpr,而不是const,因为它们可以在编译时计算:

constexpr int g() { return 30; }    

constexpr int f()
{
    constexpr int x = g();
    constexpr int y = 10;

    return x + y;
}

在运行时调用f()constexprxyconst上有x y }和x)您为编译器提供了在运行时而不是编译时初始化yconstexpr的选项。使用xy上的x,编译器将在编译时计算yf(),即使在{{ 1}}在运行时执行。

但是,在其他功能中,不能始终使用constexpr。例如,如果f()g()采用参数:

constexpr int g(int z) { return z+30; }    

constexpr int f(int z)
{
    const int x = g(z);
    constexpr int y = 10;

    return x + y;
}

现在x无法标记为constexpr,因为z可能不是编译时常量,并且目前无法将其标记为此类。因此,在这种情况下,标记x const是您可以做的最佳选择。

答案 2 :(得分:3)

您不仅可以,但有时您必须如果变量发生变化),例如

constexpr size_t f(size_t n) {
    size_t val = 1;
    if (n == 0) val++;
    return val;
}
char arr0[f(0)] = {'a', 'x'};
char arr1[f(1)] = {'y'};

在C ++ 14中很好。

答案 3 :(得分:1)

通常,函数无法在编译时计算,因此无法在常量表达式中调用。将函数指定为constexpr表示如果其输入参数是常量,则可以在常量表达式中使用它。例如......

constexpr int n = func(7);

...必须在编译时进行评估。

这是constexpr在函数之前的含义。在这种情况下,并不是说函数内的局部变量不必指定为const。