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

C++ 我可以在lambda中使用constexpr值而不捕获它吗?,c++,lambda,c++14,constexpr,C++,Lambda,C++14,Constexpr,我想在lambda中使用constexpr值。阅读答案 ,我认为以下方法应该有效: #include<array> int main() { constexpr int i = 0; auto f = []{ std::array<int, i> a; }; return 0; } clang 3.8编译了它,但gcc 4.9.2失败: 错误:“i”的值在常量表达式中不可用 这应该被认为是Clang3.

我想在lambda中使用constexpr值。阅读答案 ,我认为以下方法应该有效:

  #include<array>
  int main()
  { 
    constexpr int i = 0;
    auto f = []{  
      std::array<int, i> a;
    };
    return 0;
  }
clang 3.8编译了它,但gcc 4.9.2失败:

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

这应该被认为是Clang3.8中的一个bug吗

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

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

一个变量
x
,其名称显示为可能计算的表达式
ex
是由
ex
使用的odr,除非将左值转换为右值 (4.1)to
x
生成一个不调用 任何非平凡函数…

这一要求当然得到满足

…如果
x
是一个对象,
ex
是 表达式
e
的潜在结果集,其中 左值到右值的转换(4.1)应用于
e
,或者
e
是 废弃值表达式(第5条)

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


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

是否有任何区别?不,这不是在gcc 4.9.2下编译的,也不是在Clang 3.8.hmmm下编译的。。。。我想你考虑过定义为(临时)解决方案?但宏是邪恶的!另外,它们不能被赋予constexpr函数。@GuillaumeRacicot:这只是一个咒语。引用这里的话:“宏就像其他任何工具一样——谋杀案中使用的锤子不是邪恶的,因为它是锤子。人以这种方式使用它是邪恶的。如果你想锤进钉子,锤子是一个完美的工具。”标准似乎没有花太多的话来说明在lambdas中使用constexpr。。。示例中的代码只处理运行时使用(对吗?),并且在clang 3.8和g++4.9.2中都编译得很好。无论如何,它在clang中看起来确实是错误的。我提交了一个bug。@OlafBooij关键是它不能作为运行时(=odr-)使用,因为变量没有被捕获。它编译的事实是。。不言自明,因为它的目的是,开发人员甚至可能已经用这个确切的例子测试了东西;MSVC坚持要显式捕获
i
...
auto f = [i]{
...