什么时候是平凡的

When is a lambda trivial?

本文关键字:什么时候      更新时间:2023-10-16

什么时候保证一个lambda a是微不足道的,如果有的话?

我假设如果它只捕获平凡的类型或者什么都不捕获,那么它就是平凡的。但我没有任何标准的说法来支持这一点。

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

的例子:

#include <type_traits>
#include <iostream>
using namespace std;
int main()
{
    auto lambda = [](){};
    cout << boolalpha << is_trivially_copyable<decltype(lambda)>{} << endl;
}

这在vs140上产生false,但在vs120和clang中产生true。由于没有gcc>= 5左右,我无法测试gcc。我希望这是vs140的回归,但我不确定这里的正确行为。

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

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

…实现可以定义不同于下面描述的闭包类型,前提是这不会改变可观察对象

  • 闭包类型的大小和/或对齐,
  • 闭包类型是否可复制(条款9),
  • 闭包类型是否为标准布局类(条款9),或
  • 闭包类型是否为POD类(条款9)。

(强调我的)

解析完这句话中的双否定后,我们可以看到实现允许决定闭包类型是可复制的、标准布局的还是POD的。

请注意,相同的措辞也出现在c++ 17 (N4659)中,[expr.prim.lambda。关闭]8.1.5.1/2。

根据标准草案N4527 5.1.2/3 Lambda表达式[expr.prim.] (强调mine):

lambda表达式的类型(也是闭包对象)是唯一的、未命名的非联合类类型——称为闭包类型——其属性如下所述。这个类类型既不是聚合类型(8.5.1),也不是文字类型(3.9)。关闭类型在最小的块作用域、类作用域或包含相应lambda表达式的命名空间作用域。[注意:这决定了关联的名称空间和类的集合使用闭包类型(3.4.2)。的参数类型lambdaddeclarator不影响这些关联的命名空间和类。实现可以定义闭包类型与下面所描述的不同,只要这一点没有改变

(3.1) -闭包类型

的大小和/或对齐

(3.2) - 闭包类型是否可复制(第9条),

(3.3) -是否闭包类型是一个标准布局类(第9条),或者

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

实现应当不能将右值引用类型的成员添加到闭包类型

因此,它依赖于实现