我可以在 lambda 中使用 constexpr 值而不捕获它吗?

Can I use a constexpr value in a lambda without capturing it?

我想在 lambda 中使用 constexpr 值。阅读答案 ,我假设以下应该有效:

  #include<array>
  int main()
  { 
    constexpr int i = 0;
    auto f = []{  
      std::array<int, i> a;
    };
    return 0;
  }

但是,Clang 3.8(std=c++14)抱怨

variable 'i' cannot be implicitly captured in a lambda with no capture-default specified

这应该被视为 clang 3.8 中的错误吗?

顺便说一句:

以上代码使用 gcc 4.9.2 编译。 如果我更改 lambda 表达式以显式捕获:

...
auto f = [i]{
...

clang 3.8 编译它,但 gcc 4.9.2 失败:

error: the value of ‘i’ is not usable in a constant expression ...

Should this be considered a bug in clang 3.8?

是的。仅当 [expr.prim.lambda]/12 要求时才需要捕获:

请特别注意突出显示的示例。 f(x) 不需要捕获 x,因为它不是 odr-used(重载解析选择带有对象参数的重载)。同样的论点适用于您的代码 - [basic.def.odr]/3:

A variable x whose name appears as a potentially-evaluated expression ex is odr-used by ex unless applying the lvalue-to-rvalue conversion (4.1) to x yields a constant expression (5.20) that does not invoke any non-trivial functions…

这个要求当然可以满足

…and, if x is an object, ex is an element of the set of potential results of an expression e, where either the lvalue-to-rvalue conversion (4.1) is applied to e, or e is a discarded-value expression (Clause 5).

i 是其根据 [basic.def.odr]/(2.1) 的一组潜在结果,并且 l-t-r 转换确实在传递给对象的非类型模板参数时立即应用类型。

因此,正如我们已经表明 (12.1) 不适用 - (12.2) 显然也不适用 - Clang 拒绝您的代码段是错误的。