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 paragraph 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With