如何在lambda中使用constexpr值?

Ola*_*oij 18 c++ lambda constexpr c++14

我想在lambda中使用constexpr值.阅读使用lambda捕获的constexpr值作为数组维度的答案 ,我假设以下应该工作:

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

然而,Clang 3.8(std = c ++ 14)抱怨说

变量'i'不能在没有指定capture-default的lambda中隐式捕获

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

BTW:

上面的代码用gcc 4.9.2编译.如果我将lambda表达式更改为显式捕获:

...
auto f = [i]{
...
Run Code Online (Sandbox Code Playgroud)

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

错误:'i'的值在常量表达式中不可用...

Col*_*mbo 9

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

是的.只有在[expr.prim.lambda]/12强制执行时才需要捕获:

在此输入图像描述

请特别注意突出显示的示例.f(x)没有必要x被捕获,因为它没有使用odr(重载决策选择带有object参数的重载).相同的论证适用于您的代码 - [basic.def.odr]/3:

除非应用左值到右值转换(4.1)以产生不调用任何非平凡函数的常量表达式(5.20),否则x其名称显示为可能已评估的表达式 的变量将被ex使用.ex x

肯定满足了这一要求.

...并且,如果x是对象,ex则是表达式的潜在结果集合的元素e,其中左值到右值转换(4.1)应用于e或者e是丢弃值表达式(第5节).

i 是[basic.def.odr] /(2.1)的潜在结果集,并且ltr转换确实会立即应用,因为它传递给对象类型的非类型模板参数.

因此,正如我们已经表明(12.1)不适用 - 而(12.2)显然不适用 - 或者 - Clang拒绝你的片段是错误的.

  • 唉,C++11 整整十年之后的 MSVC 仍然没有正确实现这一点的编译器;MSVC 坚持明确捕获“i”。 (6认同)