C++ 学习计划 - 第三周第18天:Lambda表达式
第18天:Lambda表达式 学习目标 掌握C++11引入的Lambda表达式,理解函数式编程思想,学会使用Lambda表达式简化代码和提高可读性。
核心知识点 1. Lambda表达式概述 什么是Lambda表达式? Lambda表达式是C++11引入的匿名函数,它允许在需要函数的地方内联定义函数,使代码更加简洁和灵活。
基本语法 1 [捕获列表](参数列表) -> 返回类型 { 函数体 }
为什么使用Lambda?
简化代码 :减少函数对象的定义
就地定义 :在使用处直接定义逻辑
提高可读性 :逻辑更加集中
函数式编程 :支持函数式编程范式
参考资料
2. 基本Lambda表达式 简单示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 auto lambda = []() { std::cout << "Hello Lambda!" << std::endl; };lambda ();auto add = [](int a, int b) { return a + b; };int result = add (3 , 4 );auto complex = [](int x) { if (x > 0 ) { return x * 2 ; } else { return -x; } };
与STL算法结合 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 std::vector<int > numbers = {1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 }; std::vector<int > evens; std::copy_if (numbers.begin (), numbers.end (), std::back_inserter (evens), [](int n) { return n % 2 == 0 ; }); std::vector<int > squares; std::transform (numbers.begin (), numbers.end (), std::back_inserter (squares), [](int n) { return n * n; }); std::sort (numbers.begin (), numbers.end (), [](int a, int b) { return a > b; });
参考资料
3. 捕获列表 (Capture List) 值捕获 1 2 3 4 5 6 7 8 9 10 11 12 int x = 10 ;int y = 20 ;auto lambda1 = [x, y]() { std::cout << "x = " << x << ", y = " << y << std::endl; }; x = 100 ; y = 200 ; lambda1 ();
引用捕获 1 2 3 4 5 6 7 8 9 10 11 12 int x = 10 ;int y = 20 ;auto lambda2 = [&x, &y]() { std::cout << "x = " << x << ", y = " << y << std::endl; x = 100 ; y = 200 ; }; lambda2 ();std::cout << "修改后: x = " << x << ", y = " << y << std::endl;
混合捕获 1 2 3 4 5 6 7 8 9 10 int a = 1 , b = 2 , c = 3 , d = 4 ;auto lambda3 = [a, &b, c, &d]() { std::cout << "a = " << a << ", b = " << b << ", c = " << c << ", d = " << d << std::endl; b = 20 ; d = 40 ; };
默认捕获 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 int x = 10 ;int y = 20 ;int z = 30 ;auto lambda4 = [=]() { std::cout << "x = " << x << ", y = " << y << ", z = " << z << std::endl; }; auto lambda5 = [&]() { std::cout << "x = " << x << ", y = " << y << ", z = " << z << std::endl; x = 100 ; }; auto lambda6 = [=, &x]() { std::cout << "x = " << x << ", y = " << y << ", z = " << z << std::endl; x = 200 ; };
参考资料
4. 参数列表和返回类型 参数列表 1 2 3 4 5 6 7 8 9 10 11 12 13 auto lambda1 = []() { std::cout << "无参数Lambda" << std::endl; };auto lambda2 = [](int x) { return x * 2 ; };auto lambda3 = [](int a, int b, int c) { return a + b + c; };std::vector<int > numbers = {1 , 2 , 3 , 4 , 5 }; int sum = std::accumulate (numbers.begin (), numbers.end (), 0 , [](int acc, int n) { return acc + n * n; });
返回类型 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 auto lambda1 = [](int x) { return x * 2 ; };auto lambda2 = [](int x) -> int { return x * 2 ; };auto lambda3 = [](int x) -> double { return x * 2.5 ; };auto lambda4 = [](int x) -> std::pair<int , int > { return {x, x * x}; }; auto lambda5 = [](int x) -> int { if (x > 0 ) { return x * 2 ; } else { return -x; } };
参考资料
5. 泛型Lambda (C++14) 基本语法 1 2 3 4 5 6 7 8 9 10 11 auto print = [](const auto & value) { std::cout << value << " " ; }; std::vector<int > numbers = {1 , 2 , 3 , 4 , 5 }; std::vector<double > doubles = {1.1 , 2.2 , 3.3 , 4.4 , 5.5 }; std::for_each(numbers.begin (), numbers.end (), print); std::for_each(doubles.begin (), doubles.end (), print);
泛型Lambda与STL算法 1 2 3 4 5 6 7 auto multiply = [](const auto & a, const auto & b) { return a * b; }; std::cout << "multiply(3, 4) = " << multiply (3 , 4 ) << std::endl; std::cout << "multiply(2.5, 3.0) = " << multiply (2.5 , 3.0 ) << std::endl;
参考资料
6. Lambda表达式与函数对象 函数对象 vs Lambda 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Multiplier {private : int factor; public : Multiplier (int f) : factor (f) {} int operator () (int x) const { return x * factor; } }; Multiplier multiplier (3 ) ;std::transform (numbers.begin (), numbers.end (), result.begin (), multiplier); std::transform (numbers.begin (), numbers.end (), result.begin (), [](int x) { return x * 3 ; });
std::function 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include <functional> std::function<int (int )> func = [](int x) { return x * 2 ; }; int result = func (5 );std::vector<std::function<void ()>> handlers; handlers.push_back ([]() { std::cout << "Handler 1" << std::endl; }); handlers.push_back ([]() { std::cout << "Handler 2" << std::endl; }); for (const auto & handler : handlers) { handler (); }
参考资料
7. Lambda表达式高级应用 递归Lambda 1 2 3 4 5 6 7 8 9 auto factorial = [](int n) { auto impl = [](int n, auto & self) -> int { return n <= 1 ? 1 : n * self (n - 1 , self); }; return impl (n, impl); }; std::cout << "5! = " << factorial (5 ) << std::endl;
立即调用Lambda 1 2 3 4 5 6 7 8 9 10 11 12 13 int result = [](int x, int y) { return x * x + y * y; }(3 , 4 ); const auto data = []() { std::vector<int > vec; for (int i = 0 ; i < 10 ; ++i) { vec.push_back (i * i); } return vec; }();
参考资料
实用教程和文档 官方文档
优质教程
实战案例
今日练习 基础练习
实现一个函数式编程工具类,提供map、filter、reduce等功能
编写一个事件处理器,使用Lambda表达式处理不同类型的事件
实现一个配置管理器,使用Lambda表达式进行配置验证和处理
算法题推荐
LeetCode 49. Group Anagrams - 使用Lambda表达式进行字符串处理
LeetCode 347. Top K Frequent Elements - 使用Lambda表达式进行排序和比较
LeetCode 451. Sort Characters By Frequency - 使用Lambda表达式进行字符频率排序
LeetCode 692. Top K Frequent Words - 使用Lambda表达式进行单词频率排序
学习要点总结
语法结构 :掌握Lambda表达式的完整语法
捕获列表 :理解值捕获、引用捕获和混合捕获
与STL结合 :熟练使用Lambda表达式与STL算法
泛型Lambda :掌握C++14的泛型Lambda特性
函数式编程 :理解函数式编程思想
下一天预告 明天我们将学习移动语义,包括左值与右值、移动构造函数、std::move等C++11的重要特性。
上一天:智能指针 | 返回第三周总览 | 下一天:移动语义