引言:本文主要介绍C++11新特性的lambda函数用法。
语法格式及含义
1 | [外部变量访问方式说明符] (参数) mutable noexcept/throw() -> 返回值类型 |
- [外部变量访问方式说明符]
[]是lambda表达式标识符,不可省略。在方括号内部,可以注明当前 lambda 函数的函数体中可以使用哪些外部变量。所谓外部变量,指的是和当前 lambda 表达式位于同一作用域内的所有局部变量。注意区分外部变量和全局变量。外部变量格式有如下几种书写方式:
外部变量格式 | 功能 |
---|---|
[] | 空方括号表示当前 lambda 匿名函数中不导入任何外部变量。 |
[=] | 只有一个 = 等号,表示以值传递的方式导入所有外部变量; |
[&] | 只有一个 & 符号,表示以引用传递的方式导入所有外部变量; |
[val1,val2,…] | 表示以值传递的方式导入 val1、val2 等指定的外部变量,同时多个变量之间没有先后次序; |
[&val1,&val2,…] | 表示以引用传递的方式导入 val1、val2等指定的外部变量,多个变量之间没有前后次序; |
[val,&val2,…] | 以上 2 种方式还可以混合使用,变量之间没有前后次序。 |
[=,&val1,…] | 表示除 val1 以引用传递的方式导入外,其它外部变量都以值传递的方式导入。 |
[&,val1,…] | 表示除 val1 以值传递的方式导入外,其它外部变量都以引用传递的方式导入。 |
[this] | 表示以值传递的方式导入当前的 this 指针。 |
注意,单个外部变量不允许以相同的传递方式导入多次。例如 [=,val1] 中,val1 先后被以值传递的方式导入了 2 次,这是非法的。
- (参数)
和普通函数的定义一样,lambda 匿名函数也可以接收外部传递的多个参数。和普通函数不同的是,如果不需要传递参数,可以连同 () 小括号一起省略;
- mutable
此关键字可以省略,如果使用则之前的 () 小括号将不能省略(参数个数可以为 0)。默认情况下,对于以值传递方式引入的外部变量,不允许在 lambda 表达式内部修改它们的值(可以理解为这部分变量都是 const 常量)。而如果想修改它们,就必须使用 mutable 关键字。(修改的是拷贝的那一份,并不会修改真正的外部变量)
- noexcept/throw()
可以省略,如果使用,在之前的 () 小括号将不能省略(参数个数可以为 0)。默认情况下,lambda 函数的函数体中可以抛出任何类型的异常。而标注 noexcept 关键字,则表示函数体内不会抛出任何异常;使用 throw() 可以指定 lambda 函数内部可以抛出的异常类型。值得一提的是,如果 lambda 函数标有 noexcept 而函数体内抛出了异常,又或者使用 throw() 限定了异常类型而函数体内抛出了非指定类型的异常,这些异常无法使用 try-catch 捕获,会导致程序执行失败。
- -> 返回值类型
指明 lambda 匿名函数的返回值类型。值得一提的是,如果 lambda 函数体内只有一个 return 语句,或者该函数返回 void,则编译器可以自行推断出返回值类型,此情况下可以直接省略。
- 函数体
除了可以使用传入参数外,还可以使用指定的外部变量和全局变量。(外部变量会受到以值传递还是以引用传递方式引入的影响,而全局变量则不会。换句话说,在 lambda 表达式内可以使用任意一个全局变量,必要时还可以直接修改它们的值)