What’s Lambda Expression?
Lambda 表达式是 C++11 标准引入的一种用于创建匿名函数对象的强大特性。它允许你在需要函数的地方内联地定义函数,而无需单独命名和定义函数或函数对象,这使得代码更简洁、更易读,尤其在使用 STL 算法时。
Basic Syntax
1 2 3
| [ 捕获列表 ] ( 参数列表 ) -> 返回类型 { }
|
- 捕获列表 (Capture Clause) [ ]
这是 Lambda 表达式的开端,也是它最独特和强大的部分。它定义了Lambda函数体中可以访问的外部作用域中的变量及其访问方式。
- [] :空捕获列表,表示不捕获任何外部变量。
- [=] :以值捕获的方式捕获所有外部变量。
Lambda 体内使用的是这些变量的副本,修改副本不会影响外部变量。 - [&] :以引用捕获的方式捕获所有外部变量。
Lambda 体内使用的是这些变量本身,修改它们会影响外部变量。
1 2 3
| int x = 10,y =5; auto f = [=]() { return x + y; }; auto g = [&]() { x += y; };
|
- [var] :仅以值捕获的方式捕获特定变量 var。
1 2 3 4 5
| int x=10; auto f=[x]() -> int{ return x+1; }; std::cout<<f();
|
- [&var] :仅以引用捕获的方式捕获特定变量 var。
1 2 3 4
| int x = 10; auto f = [&x]() { x += 1; }; f(); std::cout << x;
|
- 混合捕获:可以组合使用,例如 [=, &x] 表示以值捕获所有外部变量,但变量 x 除外,它以引用方式捕获。[&, x] 则表示以引用捕获所有外部变量,但变量 x 以值方式捕获。
1 2 3 4 5 6
| int x = 10, y = 20; auto f = [x, &y]() { y+=x; return x + y; }; std::cout << f();
|
- 参数列表 (Parameter List) ( )
- 返回类型 (Return Type) -> return_type
可以显式地使用 -> 后缀语法来指定 Lambda 的返回类型。在大多数情况下,编译器可以自动推导出返回类型
1 2
| auto simple = [](int x) { return x * 2; };
|
1 2
| auto explicit_return = [](int x) -> double { return x * 2.5; };
|
当函数体包含多个返回语句且类型不同,或者返回语句过于复杂编译器无法推导时,需要显式指定。
1 2 3 4
| auto fixed = [](bool test) -> double { if (test) return 10; else return 20.0; };
|
- 函数体 (Body) { }
和普通函数一样,包含了 Lambda 被调用时要执行的代码。
Application
- 与 STL 算法配合使用
简单的说就是STL算法用来遍历容器,使用Lambda表达式设定特定的程序,来处理不同的任务!
std::sort 自定义排序规则
方法1:使用默认排序(升序)
1 2 3
| std::vector<int> numbers = {4, 2, 8, 5, 1}; std::sort(numbers.begin(), numbers.end());
|
方法2:使用函数指针(传统方式,不推荐)
1 2 3 4 5 6
| bool compareDescending(int a, int b) { return a > b; } std::sort(numbers.begin(), numbers.end(), compareDescending);
|
方法3:使用Lambda表达式(现代方式,推荐!)
1 2 3 4 5 6 7 8 9 10
| std::sort(numbers.begin(), numbers.end(), [](int a, int b) { return a < b; });
std::sort(numbers.begin(), numbers.end(), [](int a, int b) { return a > b; });
|
1 2 3 4 5 6 7 8 9
| std::vector<int> mixed = {3, 6, 1, 8, 2, 7}; std::sort(mixed.begin(), mixed.end(), [](int a, int b) { if (a % 2 == 0 && b % 2 != 0) return true; if (a % 2 != 0 && b % 2 == 0) return false; return a < b; });
|
std::for_each 对每个元素执行操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| std::vector<std::string> words = {"apple", "banana", "cherry", "date"};
for (const auto& word : words) { std::cout << word << " "; } std::cout << std::endl;
std::for_each(words.begin(), words.end(), [](const std::string& w) { std::cout << w << " "; }); std::cout << std::endl;
std::vector<int> nums = {1, 2, 3, 4, 5}; std::for_each(nums.begin(), nums.end(), [](int& n) { n *= 2; });
|
std::find_if 按条件查找元素
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
| struct Person { std::string name; int age; }; std::vector<Person> people = { {"Alice", 25}, {"Bob", 17}, {"Charlie", 30}, {"David", 16} };
auto adultIt = std::find_if(people.begin(), people.end(), [](const Person& p) { return p.age >= 18; });
if (adultIt != people.end()) { std::cout << "First adult: " << adultIt->name << std::endl; }
auto nameIt = std::find_if(people.begin(), people.end(), [](const Person& p) { return !p.name.empty() && p.name[0] == 'C'; });
|
std::count_if 统计满足条件的元素个数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| std::vector<int> scores = {85, 92, 78, 90, 65, 88, 72, 95, 60, 81};
int passCount = std::count_if(scores.begin(), scores.end(), [](int score) { return score >= 60; });
int excellentCount = std::count_if(scores.begin(), scores.end(), [](int score) { return score >= 90; });
std::cout << "Pass: " << passCount << ", Excellent: " << excellentCount << std::endl;
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| std::vector<int> numbers = {1, 4, 9, 16, 25};
std::vector<double> roots(numbers.size()); std::transform(numbers.begin(), numbers.end(), roots.begin(), [](int n) { return std::sqrt(n); });
std::vector<std::string> strNumbers(numbers.size()); std::transform(numbers.begin(), numbers.end(), strNumbers.begin(), [](int n) { return std::to_string(n); });
|
- 简化代码,增强可读性