Default constructor for lambdas

180 views
Skip to first unread message

Vincent Reverdy

unread,
Dec 16, 2016, 5:47:45 PM12/16/16
to ISO C++ Standard - Future Proposals
Hello.

What is the reason why lambdas have no default constructor? Is there any technical reason behind that, or is it a pure design decision?

I have a use case where not having a default constructor for lambda is annoying.

Given C++17 class template deduction, I would like to be able to do:

template <class F>
class object
{
   
constexpr object(F) {}            // Constructor
   
constexpr void execute() {F()();} // Default-construct the lambda, and run it
};

object myobject([](){std::cout<<"Hello world!"<<std::endl;});
myobject
.execute();

What do you think? Remarks? Comments?

Thank you very much.
Best,
Vincent Reverdy

D. B.

unread,
Dec 16, 2016, 6:15:15 PM12/16/16
to std-pr...@isocpp.org
My uninformed guess is that it's because lambdas are primarily intended to be called and passed around as opaque entities, and the fact they have types is a kind of unavoidable baggage, rather than a design goal or something to exploit. But I'm quite likely to be wrong :)

Could you elaborate on where an ability to construct another instance of the templated type would be useful? As written, I can't see why you wouldn't just stash it as a member in the ctor and call it again later. it seems wasteful, constructing a lambda initially, only to discard it and rebuild on each execute(); the one in the ctor is merely a surrogate for type deduction. If the type had mutable or static members, that could cause different behaviour, but then why would you pass such a type into the above pattern? There must be motivations this doesn't illuminate (or maybe it's just too late in the day for me to be thinking about things like this!)

szollos...@gmail.com

unread,
Dec 16, 2016, 6:21:12 PM12/16/16
to ISO C++ Standard - Future Proposals
Hi,

Minor thing - it will only work if all the captures of the lambda are copyable. Even then it's non-trivial sometimes to choose schematics.

Thanks,
-lorro

Nicol Bolas

unread,
Dec 16, 2016, 11:46:08 PM12/16/16
to ISO C++ Standard - Future Proposals

I think this would be much more reasonable as this:

struct HelloWorld { void operator()() {std::cout<<"Hello world!"<<std::endl;}};

object myobject(HelloWorld());

I generally consider globally-scoped lambdas like these to be dubious constructs. There's nothing to capture, so the only thing you're doing is making it slightly more convenient to define a struct with an operator() overload.

That being said, I'm not against the feature, so long as it only applies to lambdas that have no captures. There was a long thread on this forum about applying default constructors to capturing lambdas, and it was generally agreed on that it broke the meaning of the lambda.

Thiago Macieira

unread,
Dec 17, 2016, 1:33:57 AM12/17/16
to std-pr...@isocpp.org
On sexta-feira, 16 de dezembro de 2016 14:47:45 PST Vincent Reverdy wrote:
> Hello.
>
> What is the reason why lambdas have no default constructor? Is there any
> technical reason behind that, or is it a pure design decision?

What would you initialise the captures-by-reference to?

[i] { ++i; }

has struct equivalent:

struct Lambda
{
int &i;
Lambda(int &i) : i(i) {}
operator()() { ++i; }
};

The above cannot have a default constructor.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center

Thiago Macieira

unread,
Dec 17, 2016, 1:48:23 AM12/17/16
to std-pr...@isocpp.org
On sexta-feira, 16 de dezembro de 2016 22:33:51 PST Thiago Macieira wrote:
> [i] { ++i; }

I meant [&i] { ++i; }
Reply all
Reply to author
Forward
0 new messages