Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.
  1. What is the necessity to use lambda functions and expressions in C++?

  2. Can you explain or show through examples how to use lambda functions and expressions?

  3. I already gone through the related Wikipedia page, but I got only few ideas regarding this. Are there more resources I can read?

May I know which compilers will fully support this lambda feature? Some answers I found are VS10 and GCC5 compilers. Is there any online compilers which are supporting this feature?

share|improve this question

migrated from stackoverflow.com Aug 3 '11 at 10:21

This question came from our site for professional and enthusiast programmers.

    
in a word: <algorithms> –  jk. Feb 5 '13 at 10:17
    
There is never a necessity to use anything. All there is are cases where the new features make code significantly simpler. –  Jan Hudec Feb 5 '13 at 11:45
add comment

3 Answers

The use case for lambdas are those situations where you need to create a simple small function object that is not meant to be reused. Lambdas represent a simple way of doing so. Some of the basic use cases will involve using the standard library algorithms:

std::vector<double> data = get_data();
std::transform( data.begin(), data.end(), data.begin(), [](double x){ return x*x*height; } );

That is a simple concise way of iterating over a container of double performing an operation to all the elements. Before C++0x you needed to create a function or function object to pass as an argument. The language did not allow local types to be used with templates which meant that you needed to go outside of the function you are implementing to create just a simple function.

Lambdas are not really an enabling feature (they don't allow you to do anything that couldn't be done without them). As an example, in C++0x local types can be used with templates (there was never a reason to disallow it, it just happened to be), so you could write:

std::vector<double> data = get_data();
struct operation {                                 // 1
   double h;                                       // 2
   operation( double h ) : h(h) {}                 // 3
   double operator()( double x ) { return x*x*h; } // 4
};
std::transform( data.begin(), data.end(), data.begin(), operation(height) );

The code does basically the same thing, but there is a bit of extra boiler plate (code that is not part of the logic, but is needed for the language. You need to declare it to be a type [1], and provide the implementation of operator() [4]. Because local types do not capture anything from the context you need to create a member attribute to hold the height [2], and you need to pass it in the construction [3]. Lambdas just allow a concise way of expressing that.

There are multiple other situations where you might want to create small function objects that perform a small operation and lambdas might help. Consider, for example printing the contents of the vector above. It could be done in C++03 as:

std::copy( data.begin(), data.end(), std::ostream_iterator<double>(std::cout, " ") );

Or with a simple lambda:

std::for_each( data.begin(), data.end(), []( double x ) { std::cout << x << " "; } );

Which is more readable in this case? Either one, but there are many circumstances where there is no iterator adaptor (std::ostream_iterator) or prebuilt functor that fits your needs. Finally, you can think that lambdas might be used to remove the need for std::bind to create generalized functors.

Currently (with boost::bind, or in C++0x without lambdas) you can create a function adapters with bind. One piece of code that I have used this before was while writing a Timer type. The idea is that you create one such object, and you register callbacks with a given period. Every time that the period completes, the timer will call all of the registered objects.

struct console {
   std::ostream& out;
   console( std::ostream& o ) : out(o) {}
   void print( std::string const & msg ) {
      out << msg;
   }
};
Timer t;
console c( std::cout );
console e( std::cerr );
t.register( 1, std::bind(&console::print, &c, ".") );
t.register( 5, std::bind(&console::print, &e, "E") );

Assume that console is a much more complex class. The generalized function lets you adapt the signature of the caller (the timer will call a function<void ()>) with the signature of the function being called. In this case, it ill call the print method in an object of type console adding an extra argument. The above code will print . every second to cout, and E every 5 seconds to cerr. The registration of the callbacks can be replaced by a lambda:

t.register( 1, [&c]() { c.print("."); });
t.register( 5, [&e]() { e.print("E"); });

Again, nothing new, the same thing can be achieved with a generalized functor (or with more code with a local type), but it improves usability of the language.

Overall, what lambdas let you do is creating concise in place functions when you don't need that functionality to be reused from other parts of the code.

share|improve this answer
    
+1, much better answer than mine –  Moo-Juice Aug 3 '11 at 7:49
add comment

C++ is a great language. However, unlike languages such as C# or Java, if you want to call a function without its name, it makes it a bit difficult. Firstly, we have to deal with function pointers which are very specific (is it a member of a class? Is not not? What is the exact signature?). This is a surmountable problem but it shouldn't be this way.

If I were an API author, I am limited as to what I can do with regard to calling functions anonymously. I can allow a programmer to override some method, which isn't always ideal. What would be great, is if they could just specify a function (global or not), that gets called. Lambdas are great for this.

Before lambdas:

virtual void OnPaint(Context& dc);

Yup, we have to override that which means creating a new class and deriving from it and ensuring that our "control" gets created. Now, thanks to lambdas (assuming the UI framework in question supports them):

someWindow.OnPaint += [](Context& dc)
{
    // do some painting
}

The fact that lambdas have a type means we can put them in a vector. No longer does that vector have to be a specific type of function pointer (remember non members and members have different signatures). We can arbitrarily assign functions to things. Either inline, or not. This is very, very powerful.

share|improve this answer
    
"No longer does that vector have to be a specific type" - are you really just talking about pointer-to-free-function vs. pointer-to-member-function? –  Oli Charlesworth Aug 3 '11 at 6:53
1  
@Oli Charlesworth, I was referring to the fact that you can create a vector that takes a std::function of some sort, whereas prior to lambdas, you would have to use trickery to be able to use member functions and non-member functions in the same thing (given that their function pointers are fundamentally different) –  Moo-Juice Aug 3 '11 at 6:58
2  
Ouch... C# delegate syntax... I'd rather have a named function (someWindow.onPaint.register( []( Context& ) { ... I am also interested in how Java makes it simpler than C++, and I cannot think of a way. It allows for local unnamed types, but that and lambdas are not exactly the same: in Java you need to implement a particular interface in each situation. –  David Rodríguez - dribeas Aug 3 '11 at 7:12
    
It should be noted that if that were a "member function", that means it captured this in some way. Which means that this lambda is now bound to the lifetime of that particular instance of the class. I hope you captured a shared_ptr or something, or else you're looking at trouble down the line. Also, before lambdas, C++ didn't have std::function either (yes, Boost did, but not the standard). It also didn't have std::bind, which you can use to bind member functions and pointers (possibly shared) to function objects. –  Nicol Bolas Aug 3 '11 at 7:45
1  
@Moo-Juice: That's what Boost is for- you could have std::function in C++03. Lambdas just make generating them more convenient. –  DeadMG Aug 3 '11 at 12:33
show 1 more comment

There are other use cases of lambdas, and that's local functions. For example, look at the Windows file iteration API.

http://msdn.microsoft.com/en-us/library/aa364418(VS.85).aspx

You have to call once, process one result, and then you can write a loop to iterate over the rest, forcing duplication in the code.

The most encapsulated and DRY-adhering way to write this is to use a lambda function. It's encapsulated to the current scope, can access local variables easily so you can do whatever logic you want easily. You call it once with the first result, and then again in the loop with the other results.

There are other similar times when writing logic that is effectively inline but still re-usable is very helpful- it keeps high encapsulation but still allows DRY.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.