Skip to content

Commit 789987e

Browse files
committed
wip: Start adding lambdas lecture
1 parent 10c44a0 commit 789987e

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed

lectures/lambdas.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
Lambdas
2+
--
3+
4+
<p align="center">
5+
<a href="https://youtu.be/blah"><img src="https://img.youtube.com/vi/blah/maxresdefault.jpg" alt="Video" align="right" width=50% style="margin: 0.5rem"></a>
6+
</p>
7+
8+
We've talked about so many things, like classes and functions but there is one more thing that modern C++ has that we did not really touch upon - lambdas.
9+
10+
Here's what they are useful for. Imagine we have a vector of people, represented as a struct `Person`, and we would like to sort them by age. We can use the standard [`std::sort`](https://en.cppreference.com/w/cpp/algorithm/sort) function for that.
11+
12+
```cpp
13+
#include <algorithm>
14+
#include <iostream>
15+
#include <string>
16+
#include <vector>
17+
18+
struct Person {
19+
std::string name;
20+
int age;
21+
};
22+
23+
void Print(const std::vector<Person>& persons) {
24+
for (const auto& person : persons) {
25+
std::cout << person.name << " " << person.age << "\n";
26+
}
27+
}
28+
29+
int main() {
30+
std::vector<Person> people{
31+
{"Gendalf", 55'000}, {"Frodo", 33}, {"Legolas", 2'931}, {"Gimli", 139}};
32+
Print(people);
33+
std::sort(
34+
people.begin(), people.end(),
35+
[](const auto& left, const auto& right) { return left.age < right.age; });
36+
std::cout << "------ sorted --------" << std::endl;
37+
Print(people);
38+
}
39+
```
40+
The third argument to the `std::sort` function here is the lambda expression that essentially stands in for a comparison operator between the objects of the person class.
41+
42+
So let's talk about lambdas! What they are, how to write them to stay safe and efficient and, yes, how they make this valid C++ code:
43+
```cpp
44+
int main() {
45+
[](){}();
46+
}
47+
```
48+
49+
<!-- Intro -->
50+
51+
## Before lambdas we had functors
52+
The concept of something "callable" that we can pass into a function or even store for a while is not new to C++. It existed long before lambdas were introduced into the language.
53+
54+
Let's pause for a moment and talk a bit about what it means that something is "callable". Essentially it means that we can call it through a `()` operator with the expected number of arguments. So if we write a function `less(const Person&, const Person&)` and pass its pointer to `std::sort` it will do the trick:
55+
```cpp
56+
#include <algorithm>
57+
#include <iostream>
58+
#include <string>
59+
#include <vector>
60+
61+
struct Person {
62+
std::string name;
63+
int age;
64+
};
65+
66+
void Print(const std::vector<Person>& persons) {
67+
for (const auto& person : persons) {
68+
std::cout << person.name << " " << person.age << "\n";
69+
}
70+
}
71+
72+
bool less(const Person& p1, const Person& p2) { return p1.age < p2.age; }
73+
74+
int main() {
75+
std::vector<Person> people{
76+
{"Gendalf", 55'000}, {"Frodo", 33}, {"Legolas", 2'931}, {"Gimli", 139}};
77+
Print(people);
78+
std::sort(people.begin(), people.end(), &less);
79+
std::cout << "------ sorted --------" << std::endl;
80+
Print(people);
81+
}
82+
```
83+
84+
But what if this is not enough? What if we need to have a certain state? For example, we wouldn't want to sort the people by their absolute age, but by the difference of their age with respect to some number, say `4242`.
85+
86+
Behold **function objects**, or **functors**. These are objects for which the function call operator is defined, or, in other words, that define an operator `()`.

0 commit comments

Comments
 (0)