了解 Lambda 闭包类型如何删除默认构造函数
从 5.1.2 开始
<块引用>[19] 与 lambda 表达式关联的闭包类型具有已删除的 (8.4.3) 默认构造函数 和已删除的复制赋值运算符.它有一个隐式声明的复制构造函数(12.8)并且可能有一个隐式声明的移动构造函数(12.8).[注意:复制/移动构造函数以相同的方式隐式定义因为任何其他隐式声明的复制/移动构造函数都将被隐式定义.――结尾说明]
我正在阅读 C++ Primer 14.8.1,它解释了编译器将 lambda 表达式转换为未命名类的未命名对象.如果删除默认构造函数,我如何定义不包含 lambda 捕获的 lambda 函数的对象?
auto g = [](){};
这在概念上与...不一样吗
类 lambdaClass{上市:lambdaClass() = 删除;lambdaClass&运算符=(const lambdaClass&)=删除;空操作符()(){ }//复制/移动隐式定义的构造函数和析构函数};汽车 g = lambdaClass();//会是一个错误,因为默认值被删除了.
如果存在捕获,则将定义一个构造函数其他而不是默认构造函数,并且可以初始化此类对象(只要传递了参数).但是如果没有捕获并删除默认构造函数,那么可以创建一个 lambda 类对象在概念上似乎并不一致.
嗯,也许 lambda 类根据其 lambda 捕获创建构造函数的概念是没有根据的,尽管 C++ Primer 中是这样描述的(我在标准中找不到它的引用),因为以下代码确实即使我从概念上期望它也不起作用:
int sz = 2;汽车 a = [sz](){ 返回 sz;};声明类型(a)b(10);//编译错误decltype(a) b = a;//虽然一切都很好
解决方案 closure 到 lambda 的关系类似于 object 到班级.
C++11 标准说闭包!类型没有默认构造函数,这是正确的,因为它没有说它没有构造函数.
lambda 用于创建闭包.但是您引用的段落将针对 C++14 更改.
ClosureType() = delete;//(直到 C++14)ClosureType(const ClosureType&) = default;//(C++14 起)ClosureType(ClosureType&&) = 默认值;//(C++14 起)
<块引用>
闭包类型不是DefaultConstructible.闭包类型具有 a 删除(C++14 前)
no(C++14 起)
默认构造函数.复制构造函数和移动构造函数被隐式声明(C++14 前)
声明为默认(C++14 起)
并且可以根据复制构造函数和移动构造函数的常用规则.
http://en.cppreference.com/w/cpp/language/lambda
From 5.1.2
[19] The closure type associated with a lambda-expression has a deleted (8.4.3) default constructor and a deleted copy assignment operator. It has an implicitly-declared copy constructor (12.8) and may have an implicitlydeclared move constructor (12.8). [ Note: The copy/move constructor is implicitly defined in the same way as any other implicitly declared copy/move constructor would be implicitly defined. ―end note ]
I'm reading through C++ Primer 14.8.1 which explains lambda expressions being translated by the compiler in to an unnamed object of an unnamed class. How is it I can I define objects of lambda functions which do not contain a lambda capture, if the default constructor is deleted?
auto g = [](){};
Is this not conceptually the same as...
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.
If there was a capture then a constructor other than the default constructor would be defined and it would be okay to initialise objects of such (as long as a parameter was passed). But if there is no capture and the default constructor is deleted, it doesn't seem consistent conceptually that a lambda class object can be created.
Edit: Hmm, maybe the conception that the lambda class creates constructors depending on its lambda captures is unfounded despite this being how it's described in C++ Primer (I can find no quote of it in the standard), because the following code does not work even though I would expect it to conceptually:
int sz = 2;
auto a = [sz](){ return sz;};
decltype(a) b(10); //compiler error
decltype(a) b = a; //all good though
解决方案
The relationship between a closure to lambda is similar to object to class.
The C++11 standard says that the closure! type has no default constructor, and that is correct because it doesn't say it has no constructor.
The lambda is used to create a closure. But your quoted parapgraph will change for C++14.
ClosureType() = delete; // (until C++14)
ClosureType(const ClosureType& ) = default; // (since C++14)
ClosureType(ClosureType&& ) = default; // (since C++14)
Closure types are not DefaultConstructible. Closure types have
a deleted (until C++14)
no (since C++14)
default constructor. The copy constructor and the move constructor areimplicitly-declared (until C++14)
declaredas defaulted (since C++14)
and may be implicitly-defined according to the usual rules for copy constructors and move constructors.
http://en.cppreference.com/w/cpp/language/lambda
相关文章