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/