C++中Lambda表达式的介绍与使用场景
C++中Lambda表达式的介绍与使用场景
技术背景
在C++中,像std::for_each和std::transform这类通用函数十分实用,但在使用时若要应用的仿函数是特定函数独有的,使用起来会比较繁琐。在C++03中,若想将仿函数局部化,编写类似局部结构体仿函数的代码是不被允许的,因为该仿函数不能传递给模板函数。
C++11引入了Lambda表达式,它是一种内联的匿名仿函数,能简洁地替代结构体仿函数,让代码更易读和维护。
实现步骤
基本Lambda表达式
最简单的Lambda表达式形式如下:
1 | |
其中,[]是捕获列表,{}是函数体。
指定返回类型
在简单情况下,Lambda的返回类型可由编译器推导得出,例如:
1 | |
但在复杂情况下,编译器无法推导返回类型,此时需显式指定,使用-> T:
1 | |
捕获变量
Lambda表达式可使用捕获列表捕获外部变量,有按值捕获和按引用捕获两种方式:
1 | |
捕获列表的常见形式有:
[&epsilon, zeta]:按引用捕获epsilon,按值捕获zeta。[&]:按引用捕获Lambda中使用的所有变量。[=]:按值捕获Lambda中使用的所有变量。[&, epsilon]:按引用捕获Lambda中使用的所有变量,但按值捕获epsilon。[=, &epsilon]:按值捕获Lambda中使用的所有变量,但按引用捕获epsilon。
C++14的初始化捕获
C++14允许在捕获列表中使用=初始化元素,例如:
1 | |
C++20的模板参数
C++20起,Lambda表达式可拥有模板参数列表:
1 | |
通用Lambda(C++14)
带有auto参数的Lambda是通用Lambda:
1 | |
核心代码
示例代码1:基本使用
1 | |
示例代码2:捕获变量
1 | |
最佳实践
- 封装算法:将算法封装在Lambda表达式中,方便传递给其他函数。例如,在使用标准库算法时,可直接使用Lambda作为操作函数。
- 代码重构:对于复杂函数中的一段代码,可将其封装为Lambda,逐步进行参数化,最终可将其提取为普通函数。
- 变量初始化:基于算法结果初始化变量,使代码更简洁。
常见问题
- 返回类型推导问题:当Lambda表达式包含多个返回语句时,编译器可能无法推导返回类型,需显式指定。
- 捕获变量问题:Lambda表达式只能捕获局部变量,不能捕获对象的成员变量。
- 与函数指针的转换问题:只有无捕获的Lambda表达式才能隐式转换为函数指针。若需要使用捕获变量的Lambda作为回调函数,可使用
std::function。
C++中Lambda表达式的介绍与使用场景
https://119291.xyz/posts/introduction-and-use-cases-of-cpp-lambda-expressions/