2015-10-07 72 views
30

什么时候拉姆达保证是微不足道的?何时是拉姆达琐碎?

我认为,如果它只捕获微不足道的类型或什么都不是,那么这将是微不足道的。尽管如此,我没有任何标准支持。

我的动机是将一些代码从Visual C++ 12移动到14,并发现一些静态断言在处理我认为是微不足道的lambdas时失败。

实施例:

#include <type_traits> 
#include <iostream> 
using namespace std; 

int main() 
{ 
    auto lambda = [](){}; 

    cout << boolalpha << is_trivially_copyable<decltype(lambda)>{} << endl; 
} 

这产生false上vs140但true在VS120和铛。由于没有gcc> = 5,我无法测试gcc。我预计这是vs140的回归,但我不确定这里的正确行为。

+4

gcc 5.2也会产生'true':[Demo](http://coliru.stacked-crooked.com/a/a7dc4ee4e32fb70a) – Jarod42

回答

30

该标准没有指定闭包类型(lambda表达式的类型)是否微不足道。它明确地将其留给实现,这使得它不可移植。恐怕你不能依靠你的static_assert产生任何一致的东西。

引用C++ 14(N4140)5.1.2/3:

...的实现可以限定不同于什么下面提供所描述的封闭类型,这并不改变的可观察行为 比通过改变其他方案

  • 的尺寸和/或封闭类型的取向,
  • 闭合类型是否是平凡能够复制(第9节),
  • 封闭类型是标准布局类(第9条),还是
  • 封闭类型是否为POD类(第9条)。

...

(重点煤矿)

那句话解析双重否定之后,我们可以看到,实现被允许决定关闭类型是平凡可复制,标准布局或POD。

+0

那么这对我来说是非常难过的:(我根本没有期待那个答案我想我学到了一个没有做出假设的教训。 – tahsmith

13

根据该草案标准N45275.1.2/3 Lambda表达式[expr.prim.lambda]重点矿山):

的类型λ-表达的(这也是 闭合对象的类型)是一个唯一的,未命名的非联合类类型 - 称为闭包类型 - 其属性如下所述。此类类型 既不是聚合(8.5.1)也不是文字类型(3.9)。关闭 类型在包含相应lambda表达式的最小块作用域,类作用域或 命名空间作用域中声明。 [ 注意:这决定了与关闭类型(3.4.2)相关联的名称空间和类别集合 。一个 lambdadeclarator的参数类型不会影响这些关联的命名空间和 类。 - 注完] 的实现可以不同地与下面描述提供这并不改变 限定闭合类型 程序的比通过变更其他的可观察行为:

(3.1) - 的大小和/或封闭类型的取向,

(3.2) - 闭合类型是否是平凡能够复制(第9节),

(3.3) - 的 闭合类型是否是一个标准的布局类(第9条)或

(3.4) - 是否 闭包类型是POD类(第9章)。

的执行应 不添加右值引用类型的成员的闭合类型

因此,它是依赖于实现的。