Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between C++0x lambdas and operator(), closure and functor

I'm confident I get the general gist of the constructs, but I can't see the purpose of them in c++. I have read the previous posts on the topic here on SO and elsewhere, but I fail to see why they should be a new language feature.

The things I would like answered is thusly

  • What is the difference between a lambda and a template argument accepting a function/functor.

  • Is a closure just a functor with some set object state (scope?)?

  • What is the "killer app" for these constructs? or perhaps the typical use case?
like image 796
Captain Giraffe Avatar asked Jan 10 '11 21:01

Captain Giraffe


2 Answers

Lambdas are really just syntactic sugar for a functor. You could do it all yourself: defining a new class, making member variables to hold the captured values and references, hooking them up in the constructor, writing operator()(), and finally creating an instance and passing it. Or you could use a lambda that's 1/10 as much code and works the same.

Lambdas which don't capture can be converted to function pointers. All lambdas can be converted to std::function, or get their own unique type which works well in templated algorithms accepting a functor.

like image 96
Ben Voigt Avatar answered Sep 20 '22 01:09

Ben Voigt


Ok, you're actually asking a bunch of different questions, possibly because you are not fully familiar with terminology. I'll try to answer all.

What's the difference between a lambda and "operator()"? - Let's reword this to, "What's the difference between a lambda and object with operator()?"

Basically, nothing. The main difference is that a lambda expression creates a functional object while an object with an operator() IS a functional object. The end result is similar enough to consider the same though, an entity that can be invoked with the (params) syntax.

What's the difference between a closure and a functor? This is also rather confused. Please review this link:

http://en.wikipedia.org/wiki/Closure_(computer_programming) http://en.wikipedia.org/wiki/Closure_(computer_programming)#C.2B.2B

So, as you can see, a closure is a kind of "functor" that is defined within a scope such that it absorbs the variables available to it within that scope. In other words, its a function that is built on the fly, during the operation of the program and that building process is parameterized by the runtime values of the scope containing it. So, in C++ closures are lambdas that use values within the function building the lambda.

What is the difference between a lambda and a template argument accepting a function/functor? - This is again confused. The difference is that they are nothing alike, really. A template "argument" accepting a function/functor is already confused wording so I'll assume by "argument" you mean "function", because arguments don't accept anything. In this case, although a lambda can accept a functor as an argument, it can't be templated, one. Two, generally the lambda is the one being passed as an argument to a function accepting a functor argument.

Is a closure just a functor with some set object state (scope?)?

As you can see by the above link, no. In fact, a closure doesn't even have state, really. A closure is built based UPON the state of some other entity that built it, within that functor though this isn't state, it's the very construction of the object.

What is the "killer app" for these constructs? or perhaps the typical use case?

I'll reword that to, "Why are these things useful?"

Well, in general the ability to treat any object as a function if it has operator() is extremely useful for a whole array of things. For one, it allows us to extend the behavior of any stdlib algorithm by using either objects or free functions. It's impossible to inummerate the vast supply of usefulnesses this has.

More specifically speaking of lambda expressions, they simply make this process yet easier. The limitations imposed by object definitions made the process of using stdlib algorithms slightly inefficient in some cases (from a development use perspective, not program efficiency). For one thing, at the time at least any object passed as a parameter to a template had to be externally defined. I believe that's also changing, but still...having to create entire objects just to perform basic things, that only get used in one place, is inconvenient. Lambda expressions allow that definition to be quite easy, within the scope of the place its being used, etc, etc...

like image 25
Edward Strange Avatar answered Sep 20 '22 01:09

Edward Strange