First of all, for whom this blog is (Ideally).
-> Someone interested in learning and at least have a good knowledge of programming in c++.
-> Want's to increase speed and code cleaner.
Regardless everyone is Welcome!!!!
What is Lambda?
Well lambda are so called anonymous functions which can sometimes really help for faster coding and ease of writing.
Basic structure of Lambda
First let's see how does a lambda look like, " [] () {} ; ".
The first part, " [] " The Capture Clause: This is the most powerful part of a lambda. It defines what the lambda can "see" from its surrounding scope.
-> []: Captures nothing. The lambda can only use its own parameters or global variables.
-> [=]: Captures all outside variables by value (makes a copy).
-> [&]: Captures all outside variables by reference (can modify the originals if '**const**' not used).
-> [var1, &var2]: Captures var1 by value and var2 by reference. You can be very specific!
The second part, " () " is for declaring our parameter's taken as input, we don't need to write the parameters taken by reference in the main scope,
for eg, if inside our main function, I declare a vector dp, and use lambda as pass by ref, I don't need to specify dp in the parameter list and can directly use it, though it has power to change its values, so if we don't want that to happen, we can use "**const** vector <...> dp" and it will no longer be a risk.
The third part, " {} " is our main body of the lambda, we will write our code for what this lambda does...
There is another thing, we also can define our return type like " [] () -> type {} " we can specifically implement a return type, if we don't then 2 cases can happen,
1) If only 1 parameter is returned, it will take it from input parameter, else
2) It will take default return type to be 'void'.
It is a good practice to write the return type in codes.
We can also declare a full fledge functions with a lambda that can use recursion as well, but then we need to be a bit more clear of the data input and output....
for eg,
function < int (int) > factorial = [] (int n) -> int {
if (n <= 1)
return 1;
else
return n * factorial (n - 1);
};
Here inside function brackets, first is the return data type and then inside "()" are the input data type.
this can perform recursion, but if you don't need something this fancy (i.e recursion), we can just write "auto get = [] () {};" and it will get our job done.
Let's take 2 Examples here where we can quickly use lambda function rather than declaring a separate function.
Custom Sorting
Lets say we have a vector of a pair of int and we want to sort it in a specific way, like non — decreasing order as per first and non — increasing as per second. We can easily and quickly pass a lambda to STL sort and get our desired result.
sort (v.begin(), v.end(), [] (auto &a, auto &b) {
if (a.first == b.first)
return a.second > b.second;
else
return a.first < b.first;
});
Quick declaration of a function
Let's say I need a function like a function for update something in a data structure and I have quite a few different parameters declared inside my solve function, what I can do is
1) make a function in global scope and pass everything to it (for eg. 10 parameters, which is a pain) or
2) quickly make a lambda inside my solve function and define it as reference "[&]", and if needed things with const, no need to write others. This is much faster to do.
auto get = [&] (int a, int b) -> void {
// some code that does something!!!!
}; // (don't forget ';' at the end)
int a, b;
for (int i = 0; i < n; ++i) {
cin >> a >> b;
get (a, b);
}
This is quite useful for quick declarations and inside scope.
There are many more use cases for simpler and less error prone codes using lambda's, like DFS, BFS, custom_hash, Predicates in STL Algorithms and so on...
This concludes my blog. Thanks for reading and happy programming!!!!
For more in-depth learning, please refer this guide by Microsoft HERE
UPD :-
For my modern friends out there, there is also a very clean way to write a recursive Lambda function like this,
"NOTE :- It uses C++-23 (that's why modern) :) ",
auto factorial = [&] (this auto&& self, int n) -> int {
if (n <= 1)
return 1;
else
return n * self(n - 1);
};
NOTE :- any name can be given instead of self
And for C++14 or later, we can also do it like this :-
1) Either use function, or (showed later in this section itself)!!
2) Use auto and create a self,
auto fac = [&](auto&& self, int x) -> int {
if (x == 0)
return 1;
return x * self(self, x - 1);
};
int ans = fac(fac, 10);
But here a very important thing to note is that, we cannot perform recursion by capture this lambda by reference, so if we have to use something from the main scope, we have to specifically use it, like
auto dfs = [&g, &vis](auto&& self, int u) -> void {
vis[u] = on;
cout << u << " ";
for (auto &x : g[u]) {
if (vis[x]) continue;
self(self, x);
}
};
Here g and vis are captured by reference and not the lambda itself!
And still I prefer just make this once, it would be a lot easier :-
function <void (int) > dfs = [&](int u) -> void {
vis[u] = on;
cout << u << " ";
for (auto &x : g[u]) {
if (vis[x]) continue;
dfs (x);
}
};
And then we can like before simply call this factorial function for our answer, and also there are so called immediately invoked lambda expressions, i.e we don't make a function with a name just use it immediately.
For eg,
([&](this auto&& self, int u) -> void {
visited[u] = true;
cout << u << " ";
for (int v : graph[u]) {
if (!visited[v]) {
self(v);
}
}
})(start_node); // Immediately invoke the lambda with the starting node.
NOTE :- any name can be given instead of self
This performs dfs only once and its not a separate named function.
There is also something called as y combinator, which can be used for recursion in lambda calculus, but I think it's a bit tricky and lengthy. I think a full named function would be better instead but anyhow it can be use with c++14 or above.
I have attached a link to a stack overflow blog about it HERE,
I was not able to find a good and somewhat complete resource for it, if you do, please write a comment about it. Thanks in advance :)
I hope this help's to become a better coder in future








