了解 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】:
closure 到 lambda 之间的关系类似于 object 到 class。
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 提到的某种虚拟参数来创建对象,如果构造函数确实存在的话。谢谢。 Alambda
只是用来创建ClosureType
的实例。
注意; C++20 将改变这一点,因为可以默认构造一个没有任何捕获的 lambda。【参考方案2】:
因为赋值的右边是一个临时对象(rvalue),所以'g'是通过move assignment来赋值的
【讨论】:
以上是关于了解 Lambda 闭包类型如何删除默认构造函数的主要内容,如果未能解决你的问题,请参考以下文章
KotlinKotlin 函数总结 ( 具名函数 | 匿名函数 | Lambda 表达式 | 闭包 | 内联函数 | 函数引用 )
KotlinKotlin 函数总结 ( 具名函数 | 匿名函数 | Lambda 表达式 | 闭包 | 内联函数 | 函数引用 )
Rust闭包和Haskell lambda有什么区别? [关闭]