什么时候 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
因此,它取决于实现。
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
因此,它取决于实现。