Lambda 闭包类型构造函数

Lambda closure type constructors

本文关键字:构造函数 类型 闭包 Lambda      更新时间:2023-10-16

cpp首选项表明lambda闭包类型构造函数有不同的规则。

默认构造 - 直到 C++14

关闭类型() = 删除;(至C++14)

闭包类型不是默认可构造的。闭包类型具有 已删除(直到 C++14)否(自 C++14 年以来)默认构造函数。

默认构造 - 自 C++14 起

闭包类型没有(自 C++14 起)默认构造函数。

默认构造 - 自 C++20 起

如果未指定捕获,则闭包类型具有默认默认值 构造 函数。否则,它没有默认构造函数(这包括 存在捕获默认值的情况,即使实际上没有 捕获任何内容)。

复制赋值运算符 - 直到 C++20

复制赋值运算符定义为已删除(和移动 未声明赋值运算符)。闭合类型不是 可复制可分配。

复制赋值运算符 - 自 C++20 起

如果未指定捕获,则闭包类型具有默认副本 分配运算符和默认的移动分配运算符。 否则,它具有已删除的复制赋值运算符(这包括 存在捕获默认值的情况,即使实际上没有 捕获任何内容)。

规则变化背后的原因是什么?标准委员会是否发现了λ闭包类型结构标准中的一些缺点?如果是这样,这些缺点是什么?

有一个缺点。我们不能像人们想要的那样"即时"使用 lambda。C++20(添加允许在未计算的上下文中使用 lambda)使此代码有效:

struct foo {
int x, y;
};
std::map<foo, decltype([](foo const& a, foo const& b) { return a.x < a.y; })> m;

注意我们如何定义内联比较函数吗?无需创建命名函子(否则可能是个好主意,但我们也不是被迫的)。而且没有必要将声明一分为二:

// C++17
auto cmp = [](foo const& a, foo const& b) { return a.x < a.y; };
std::map<foo, decltype(cmp)> m(cmp); // And also need to pass and hold it!

像这样的用法(以及更多)是进行此更改的激励因素。在上面的示例中,匿名函子类型将带来命名函子类型可以带来的所有好处。默认初始化和 EBO 其中。

相关文章: