What is lambda? You may know that it’s the eleventh letter in the Greek alphabet. Perhaps you recall from Physics that it’s the symbol used to represent wavelength in calculations, or you might have heard about it from other places. In C++, a lambda is an expression to define an anonymous function, which is an unnamed function.
Here’s the syntax for a lambda expression.
You can capture values either by copy or by reference, similar to parameters in function definitions, but with one key difference: the passed object or value has to be within the scope of where the lambda function is defined, rather than the scope of where the function is called.
When do we use this?
A quick and easy example is when you use the std::find_if(), where you pass in a comparison function (or a unary predicate) to check if an element you’re searching for is found. The function takes one parameter to compare and judge if it’s what you’re looking for.
Then how do you compare the element against what?
That’s where the capture comes in. You capture the value that you’re looking for and let the lambda compare each element against this captured value so it can tell if it’s the element you’re interested in or not.
The major advantage of using lambda expressions is that it simplifies defining functions, especially in cases where a small/simple function needs to be passed into another, just like we saw above. Without the lambda, you would have to make a whole (callback) function separately then pass it using a function pointer — imagine you have a bunch of callbacks like this in your code. Surely, writing the function inline will be much more convenient, clean and easy to read.
Of course, the lambda is not the only option. You can use functors, function objects, lambdas or function pointers to achieve the same goal.
Here is an example that passes in a functor to the std::sort function.
Below does the same, but uses a traditional C-style function pointer.
Unlike the functor case, you make a separate function then pass in a pointer to it (or the function itself since the function name itself basically denotes its function pointer). Additionally, if you need a value that the function needs to know, e.g. the value/object you’re finding as in find_if(), you’ll need to find a way to pass or bind the value/object to the function — now you can see how easy it is to “capture” values/objects in a lambda.
The lambda function, as you can see above, is dropped right into the parameters without having to define and name the function.
Lambda functions are typically used to quickly and easily define functions, often when the body is short and simple, but you may also find plenty of “long” lambdas especially when passing a callback for an asynchronous operation. Either case, there’s no doubt that lambda expressions are an easy, simple and convenient way of passing functions that C++11 gives us.