tah*_*ith 33 c++ lambda type-traits c++11
一个lambda什么时候保证是微不足道的,如果有的话?
我认为,如果它只捕获琐碎的类型或什么都没有,那将是微不足道的.我没有任何标准可以支持它.
我的动机是将一些代码从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;
}
Run Code Online (Sandbox Code Playgroud)
这false
在vs140上产生,但true
在vs120和clang中产生.由于没有gcc> = 5,我无法测试gcc.我希望这是vs140的回归,但我不确定这里的正确行为.
Rei*_*ica 31
该标准没有规定闭包类型(lambda表达式的类型)是否微不足道.它明确地将其留给了实现,这使得它不可移植.我担心你不能依靠你static_assert
生产任何一致的东西.
引用C++ 14(N4140)5.1.2/3:
...实现可以定义闭包类型与下面描述的不同,前提是这不会改变程序的可观察行为,只需更改:
- 封闭类型的大小和/或对齐方式,
- 封闭类型是否可以轻易复制(第9条),
- 闭包类型是否为标准布局类(第9条),或
- 闭包类型是否为POD类(第9条).
...
(强调我的)
解析该句子中的双重否定后,我们可以看到允许实现决定闭包类型是否可以轻易复制,标准布局或POD.
请注意,C++ 17(N4659),[expr.prim.lambda.closure] 8.1.5.1/2中也存在相同的措辞.
101*_*010 14
根据标准草案N4527 5.1.2/3 Lambda表达式[expr.prim.lambda](强调我的):
lambda-expression的类型(也是闭包对象的类型)是一个唯一的,未命名的nonunion类类型 - 称为闭包类型 - 其属性如下所述.此类类型既不是聚合(8.5.1)也不是文字类型(3.9).闭包类型在包含相应lambda表达式的最小块作用域,类作用域或命名空间作用域中声明.[注意:这确定了与闭包类型相关联的名称空间和类的集合(3.4.2).lambdadeclarator的参数类型不会影响这些关联的命名空间和类.- 结束注释] 实现可以定义闭包类型与下面描述的不同,前提是这不会改变程序的可观察行为,只需更改:
(3.1) - 封闭类型的大小和/或对齐方式,
(3.2) - 封闭类型是否可以轻易复制(第9条),
(3.3) - 闭包类型是否为标准布局类(第9条),或
(3.4) - 闭包类型是否为POD类(第9条).
实现不应将rvalue引用类型的成员添加到闭包类型
因此,它依赖于实现.