了解 Lambda 闭包类型如何删除默认构造函数

Posted

技术标签:

【中文标题】了解 Lambda 闭包类型如何删除默认构造函数【英文标题】:Understanding how Lambda closure type has deleted default constructor 【发布时间】:2015-10-02 16:30:31 【问题描述】:

从 5.1.2 开始

[19] 与 lambda 表达式相关的闭包类型有一个已删除的 (8.4.3) 默认构造函数和一个已删除的 复制赋值运算符。它有一个隐式声明的复制构造函数(12.8),并且可能有一个隐式声明的 移动构造函数(12.8)。 [注意:复制/移动构造函数以相同的方式隐式定义 因为任何其他隐式声明的复制/移动构造函数都将被隐式定义。 ——尾注]

我正在阅读 C++ Primer 14.8.1,它解释了编译器将 lambda 表达式转换为未命名类的未命名对象。如果删除了默认构造函数,我如何定义不包含 lambda 捕获的 lambda 函数对象?

 auto g = []();

这在概念上与...不同吗?

 class lambdaClass
 public:
      lambdaClass() = delete;
      lambdaClass& operator=(const lambdaClass&) = delete;
      void operator()() 

      //copy/move constructor and destructor implicitly defined
;

auto g = lambdaClass(); //would be an error since default is deleted.

如果有捕获,那么将定义一个构造函数other,而不是默认构造函数,并且可以初始化这样的对象(只要传递了一个参数)。但是如果没有捕获并且删除了默认构造函数,那么在概念上似乎并不能创建一个 lambda 类对象。

编辑:嗯,也许 lambda 类根据其 lambda 捕获创建构造函数的概念是没有根据的,尽管这是在 C++ Primer 中描述的方式(我在标准中找不到它的引用),因为以下代码确实即使我希望它在概念上起作用,也不起作用:

int sz = 2;
auto a = [sz]() return sz;;
decltype(a) b(10); //compiler error
decltype(a) b = a; //all good though

【问题讨论】:

您仍然可以执行auto g = lambdaClass(dummyLambdaTag) 之类的操作。 @Jarod42 这个dummyLambdatag 会是什么?难道不是必须是lmabda,这似乎导致了先有鸡还是先有蛋的局面 @Baruch: dummyLambdatag 将是一个空结构。非默认可构造类可能具有带参数的构造函数。 【参考方案1】:

closurelambda 之间的关系类似于 objectclass

C++11 标准closure! 类型没有默认构造函数,这是正确的,因为它没有说它没有构造函数。

lambda 用于创建闭包。但是您引用的段落将更改为 C++14

ClosureType() = delete;                     // (until C++14)
ClosureType(const ClosureType& ) = default; // (since C++14)
ClosureType(ClosureType&& ) = default;      // (since C++14)

闭包类型不是DefaultConstructible。闭包类型有 a deleted (until C++14) no (since C++14) 默认构造函数。复制构造函数和移动构造函数是 implicitly-declared (until C++14) 声明的 as defaulted (since C++14) 并且可以根据复制构造函数和移动构造函数的通常规则隐式定义。

http://en.cppreference.com/w/cpp/language/lambda

【讨论】:

所以我想它必须使用像@Jarod42 提到的某种虚拟参数来创建对象,如果构造函数确实存在的话。谢谢。 A lambda 只是用来创建ClosureType 的实例。 注意; C++20 将改变这一点,因为可以默认构造一个没有任何捕获的 lambda。【参考方案2】:

因为赋值的右边是一个临时对象(rvalue),所以'g'是通过move assignment来赋值的

【讨论】:

以上是关于了解 Lambda 闭包类型如何删除默认构造函数的主要内容,如果未能解决你的问题,请参考以下文章

KotlinKotlin 函数总结 ( 具名函数 | 匿名函数 | Lambda 表达式 | 闭包 | 内联函数 | 函数引用 )

KotlinKotlin 函数总结 ( 具名函数 | 匿名函数 | Lambda 表达式 | 闭包 | 内联函数 | 函数引用 )

Rust闭包和Haskell lambda有什么区别? [关闭]

为啥 lambda 函数默认会丢弃推导的返回类型引用?

在其他函数或循环中构造 lambda 时是不是存在性能问题?

Python之路day13-内置函数_lambda_闭包