什么时候是平凡的
When is a lambda trivial?
什么时候保证一个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
产生任何一致的东西。
…实现可以定义不同于下面描述的闭包类型,前提是这不会改变可观察对象
- 闭包类型的大小和/或对齐,
- 闭包类型是否可复制(条款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条)。
实现应当不能将右值引用类型的成员添加到闭包类型
因此,它依赖于实现
- 什么时候调用组成单元对象的析构函数
- 什么时候在C++中返回常量引用是个好主意
- 什么时候调用析构函数
- boost odeint什么时候真正调用观测者
- 编译器对数组声明大小的计算。什么时候发生?
- 什么时候最好在子进程中使用 CPU 或 I/O 密集型代码 [ C++ ]
- 您应该在什么时候创建自己的异常类型
- 我什么时候会默认(而不是删除)基类中的复制和移动操作
- 什么时候可以使用常量装饰调用我的重载函数?
- unordered_map什么时候返回 -1?
- QCoreApplication什么时候有效?
- sizeof(size_t) 和 sizeof(ptrdiff_t) 什么时候会有所不同?
- 什么时候用指针调用C++类构造函数
- 我不明白在这个例子中什么时候调用构造函数
- 如果真的需要std::move,我们应该什么时候声明右值refs
- P1008("prohibit aggregates with user-declared constructors")在实践中什么时候有用?
- 程序什么时候会创建多个堆
- 调用boost.asio的异步函数时,线程是什么时候创建的
- Swig/python : 什么时候需要 SWIG_init() ?
- 什么时候 std::initializer_list 是微不足道的可构造的?