什么时候 lambda 是微不足道的?

When is a lambda trivial?

lambda a 什么时候保证是微不足道的?

我假设如果它只捕获微不足道的类型或什么都没有,那将是微不足道的。不过我没有任何标准语言来支持它。

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

示例:

#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:

... An implementation may define the closure type differently from what is described below provided this does not alter the observable behavior of the program other than by changing:

  • the size and/or alignment of the closure type,
  • whether the closure type is trivially copyable (Clause 9),
  • whether the closure type is a standard-layout class (Clause 9), or
  • whether the closure type is a POD class (Clause 9).

...

(强调我的)

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

请注意,C++17 (N4659)、[expr.prim.lambda.closure] 8.1.5.1/2.

中也存在相同的措辞

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

The type of the lambda-expression (which is also the type of the closure object) is a unique, unnamed nonunion class type — called the closure type — whose properties are described below. This class type is neither an aggregate (8.5.1) nor a literal type (3.9). The closure type is declared in the smallest block scope, class scope, or namespace scope that contains the corresponding lambda-expression. [ Note: This determines the set of namespaces and classes associated with the closure type (3.4.2). The parameter types of a lambdadeclarator do not affect these associated namespaces and classes. — end note ] An implementation may define the closure type differently from what is described below provided this does not alter the observable behavior of the program other than by changing:

(3.1) — the size and/or alignment of the closure type,

(3.2) — whether the closure type is trivially copyable (Clause 9),

(3.3) — whether the closure type is a standard-layout class (Clause 9), or

(3.4) — whether the closure type is a POD class (Clause 9).

An implementation shall not add members of rvalue reference type to the closure type

因此,它取决于实现。