【问题标题】:Can we omit const on local variables in constexpr functions?我们可以在 constexpr 函数中省略局部变量的 const 吗?
【发布时间】:2015-11-01 15:26:21
【问题描述】:

例如:

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 声明局部变量?

具有const 局部变量的constexpr 函数是否与没有const 的函数等效

换句话说,函数上的constexpr 是否强加(暗示)const 上的局部变量?

【问题讨论】:

  • 我不同意你的假设,即省略 const 会使函数看起来“更干净”。另外,不,我不这么认为。但我不是constexprt。
  • 你甚至可以change them! (而且它合乎逻辑,它不会使函数不纯
  • @LeoHeinsaar 我认为您的意思是更少的非空白字符,因为否则它可以通过该定义以一种几乎普遍被解释为不可读的方式简单地变得“更干净”。
  • @LeoHeinsaar 所以你认为混淆的 C++ 更干净,因为它的字符更少?
  • 这里是最干净的:constexpr int f(){int x=g(),y=10;return x+y;}(说真的)

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


【解决方案1】:

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

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

当然,在相反的方向,正如在 cmets 中已经提到的:

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

【讨论】:

  • 我认为这是一个很好的答案。不加思索,它可能会让人觉得constexpr 在函数上以某种方式强加(暗示)它内部的所有内容,包括局部变量(因为,例如,您不能从中调用非 constexpr 函数)。谢谢。
  • 当然,const 局部变量不能在返回时移动。出于这个原因,我对本地人的 const 非常警惕。
【解决方案2】:

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

constexpr int g() { return 30; }    

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

    return x + y;
}

当在运行时调用f() 时,如果xy 上没有constexpr,(xy 上有或没有const),您将向编译器提供在运行时而不是编译时初始化 xy 的选项。使用xy 上的constexpr,编译器在编译时计算xy,即使f() 在运行时执行也是如此。

然而,在不同的函数中,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 是你能做的最好的。

【讨论】:

  • 要求对未更改的局部变量隐含constexpr 是否合理?
  • @LeoHeinsaar:恐怕不会。在此示例中,如果 g() 未标记为 constexpr 怎么办?在这种情况下,它的结果x 不能标记为constexpr,并且编译器有权在运行时计算g()。或许g()需要打个电话才能得到结果……
  • 哦,我明白了。这很有启发性。谢谢霍华德。
【解决方案3】:

你不仅可以,而且有时你必须ie如果变量改变了),例如

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 中很好。

【讨论】:

    【解决方案4】:

    一般来说,函数不能在编译时求值,因此不能在常量表达式中调用。将函数指定为 constexpr 表示如果其输入参数是常量,则它可以在常量表达式中使用。比如这个……

    constexpr int n = func(7);
    

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-10
      • 2019-01-17
      • 2021-10-03
      • 2021-11-18
      • 2022-01-02
      • 1970-01-01
      • 2019-09-06
      • 1970-01-01
      相关资源
      最近更新 更多