Lambda 表达式
lambde表达式是C++11增加的特性,用于定义并创建匿名的函数对象。
lambda表达式 语法格式如下:
[ capture ] ( params ) opt -> ret {
Function body;
};
capture 捕获列表 | params 参数列表 | opt 函数选项 | ret 返回值
function body 函数体
局部变量引入方式[]
[] 是Lambda表达式的开始。不可省略
符号 | 说明 |
---|---|
[] | 局部变量捕获列表,Lambda表达式不能访问外部函数体的任何局部变量 |
[a] | 在函数体内部使⽤值传递的⽅式访问a变量,注意:局部变量通过值传递进来时,默认是const |
[&b] | 在函数体内部使⽤引⽤传递的⽅式访问b变量 |
[=] | 函数外的所有局部变量都通过值传递的⽅式使⽤, 函数体内使⽤的是副本 |
[&] | 以引⽤的⽅式使⽤Lambda表达式外部的所有变量 |
[=, &foo] | foo使⽤引⽤⽅式, 其余是值传递的⽅式 |
[& foo] | foo使⽤值传递⽅式,其余引⽤传递 |
[this] | 在函数内部可以使⽤类的成员函数和成员变量,= 和 & 形式也都会默认引⼊ |
我们发现在func2使用引用传递对b变量的赋值,并没能改变func3中b的值。由此可见,值的捕获并不会在Lambda运行时,而是在创建时。
注意:
1) 由于使用引用方式捕获对象会有局部变量释放了而Lambda函数还没有被调用的情况。如果执行Lambda函数,那么引用传递方式捕获进来的局部变量的值不可预知。所以绝大多数场合使用的形式为: [=] () { }
2)捕捉列表不允许变量重复传递,否则就会导致编译错误。比如[=, a],重复捕获a。
函数参数(params)
类似于函数定义中的小括号表示函数接收的参数类型和个数。参数可以通过值和引用两种方式传递。函数参数部分可以省略,相当于无参函数。
选项(opt)
Opt 部分是可选项,最常⽤的是 mutable声明 ,这部分可以省略。
Lambda表达式外部的局部变量通过值传递进来时,其默认是 const,所以不能修改这个局部变量的拷贝,加上mutable 就可以修改。
Lambda表达式的返回类型(->ret)
可以指定 Lambda表达式 返回值类型;如果不指定返回值类型,则编译器会根据代码实现为函数推导一个返回类型;如果没有返回值,则可忽略此部分。
函数体 {function body}
function body可为空,{}不能省略。
C++11中最简单的Lambda
在lambda函数定义中,参数列表和返回值类型都是可选部分,而捕捉列表和函数体可以为空。因此C++11中最简单的lambda函数为:[]{};
注意:lambda表达式之间不能相互赋值,即使看起来类型相同