lambda表达式

语法结构

lambda表达式也称为匿名函数,其基本语法结构如下:

其中capture是捕获列表,params是参数列表,opt是函数选项,retureType是返回值类型,body是函数体。

在lambda表达式中:

如果没有在[]中捕获局部变量,那么在匿名函数的函数体中无法访问它们。进一步的,还可以给匿名函数增加函数参数,以及指定函数返回类型。

Note

捕获列表捕获的是局部变量,全局变量不需要捕获。

引用捕获与值捕获

如果想要通过捕获列表改变局部变量的值,函数选项的位置加上mutable关键字才能对局部变量进行修改操作,但这样做也并不能修改局部变量实际的值。

联想到常规函数的值传递场景,想要真正通过形参改变实参,形参需要写成引用形式。

那么对于匿名函数而言,如果想要在匿名函数中修改捕获的变量其本身的值,那么应该采用的是引用捕获

(1)lambda表达式的参数列表与普通函数的参数列表一样,如果没有参数,则参数列表可以省略不写;

(2)如果没有需要捕获的内容,需要写上[];

(3)选项如非必需,可以省略:

  • mutable: 可以修改按值传递进来的拷贝(注意是能修改拷贝,而不是值本身)

  • noexcept: noexcept 是一种约定,向编译器和调用者保证函数不会抛出异常。如果违反了这个约定,程序的行为将是未定义的,通常会导致程序终止。

(4)返回类型可以省略。一般情况下,不指定lambda表达式的返回值,编译器会根据return语句自动推导返回值的类型,但需要注意的是labmda表达式不能通过列表初始化自动推导出返回值类型。

lambda表达式的返回值

lambda表达式本身的返回值是一个函数对象(function object),也称为闭包对象(closure object)。这个对象的类型是编译器生成的唯一匿名类型。

每个lambda表达式都有唯一的匿名类型

lambda表达式实际上是编译器生成的类的语法糖:

无捕获Lambda

有捕获Lambda

lambda表达式的存储和传递

lambda表达式的大小

总结

Lambda表达式本身的返回值是:

  1. 函数对象:具有唯一匿名类型的可调用对象

  2. 闭包对象:包含捕获变量的状态

  3. 编译器生成的类实例:重载了operator()的对象

  4. 可转换性

    • 无捕获lambda → 函数指针

    • 有捕获lambda → 只能用std::function或模板

关键特点:

Lambda表达式返回的不是函数执行的结果,而是一个可以被调用的函数对象本身。

STL(Standard Template Library)提供了丰富的算法库,这些算法定义在<algorithm>头文件中。以下是按功能分类的常用算法:

for_each函数

std::for_each 是 STL 中最常用的算法之一,用于对容器中的每个元素执行指定的操作。

基本语法

参数说明:

基本用法

1. 使用普通函数

2. 使用 Lambda 表达式

3. 使用函数对象(Functor)

4. 返回值的使用

std::for_each 返回传入的函数对象,这在某些情况下很有用:

查找算法

find

排序算法

修改算法

copy

transform

fill和generate

删除算法

数值算法

集合算法

堆算法

排列算法

分区算法

最值算法

比较算法