Generic lambda expressions
Due to the numerous benefits brought by lambda expressions, people started writing many temporary small functions (no need to name them! Haha). However, sometimes only the parameter types differ while the logic remains essentially the same, but you still have to write another lambda expression, which doesn’t look very clean. For example, see the following two cases of adding two numbers, differing only in that one uses int
and the other uses double
types.
1
2
3
auto lambda = [](int a, int b) {
return a + b;
};
1
2
3
auto lambda = [](double a, double b) {
return a + b;
};
This issue can be solved in C++14!
In C++14, generic lambda expressions introduce a powerful feature that allows lambda expressions to accept parameters of any type without pre-specifying the parameter types. This makes lambda expressions more flexible when using templates and generic programming.
1 Basic Generic Lambda Expression
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
int main() {
auto add = [](auto a, auto b) {
return a + b;
};
std::cout << "add(1, 2) = " << add(1, 2) << std::endl;
std::cout << "add(1.5, 2.5) = " << add(1.5, 2.5) << std::endl;
std::cout << "add(std::string(\"Hi \"), \"Kobe\") = " << add(std::string("Hi "), "Kobe") << std::endl;
return 0;
}
The output is as follows, where data of any type can be used as long as operator+
is defined.
2 Using Generic Lambda Expressions in STL Algorithms
Simply put, it makes the code easier to write.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> numbers = { 101, 102, 103, 104, 105 };
std::for_each(numbers.begin(), numbers.end(), [](auto n) {
std::cout << n << " ";
});
std::cout << std::endl;
std::transform(numbers.begin(), numbers.end(), numbers.begin(), [](auto n) {
return n * 2;
});
std::for_each(numbers.begin(), numbers.end(), [](auto n) {
std::cout << n << " ";
});
std::cout << std::endl;
return 0;
}
The output is as follows.
Use Cases
- Handling Heterogeneous Data: When you need to handle data of different types, generic lambda expressions can avoid the need to define multiple overloaded functions.
- Templated Algorithms: When using STL algorithms, generic lambda expressions can enhance code flexibility and reusability.
- Simplifying Code: In generic programming, using generic lambda expressions can make the code more concise and readable, avoiding unnecessary template code.
Can Generic Lambda Expressions Replace Templates!?
Lambda Expressions vs. Templates: Temporary Small Functions: Lambda expressions are more suitable for simple temporary functions, especially in algorithms and callbacks. Complex Generic Logic: Templates are more suitable for handling complex generic logic and type inference, such as generic containers, algorithms, and classes. Readability and Conciseness: Lambda expressions generally excel in code conciseness and readability, but templates may provide a clearer structure when logic becomes complex.
1
2
3
4
5
6
7
8
template<typename T>
void printVector(const std::vector<T>& vec) {
for (const T& elem : vec) {
std::cout << elem << " ";
}
std::cout << std::endl;
}
In this example, the templated function printVector can handle different types of std::vector, demonstrating the versatility and power of templates in dealing with different types.
Conclusion No!!!