c++11:lambda表达式

来源:互联网 发布:南京婚纱摄影软件 编辑:程序博客网 时间:2024/05/29 14:12

lambda 表达式可以方便地构造匿名函数,如果你的代码里面存在大量的小函数,而这些函数一般只被调用一次,那么不妨将他们重构成 lambda 表达式。

C++11 的 lambda 表达式规范如下:

[ capture ] ( params ) mutable exception attribute -> ret { body } (1)
[ capture ] ( params ) -> ret { body } (2)
[ capture ] ( params ) { body } (3)
[ capture ] { body } (4)

其中
(1) 是完整的 lambda 表达式形式,
(2) const 类型的 lambda 表达式,该类型的表达式不能改捕获(“capture”)列表中的值。
(3)省略了返回值类型的 lambda 表达式,但是该 lambda 表达式的返回类型可以按照下列规则推演出来:
如果 lambda 代码块中包含了 return 语句,则该 lambda 表达式的返回类型由 return 语句的返回类型确定。如果没有 return 语句,则类似 void f(…) 函数。
(4)省略了参数列表,类似于无参函数 f()。

此外,params 指定 lambda 表达式的参数。
ret是返回值类型。(选填)
body是函数体
exception说明lambda表达式是否抛出异常以及何种异常
attribute用来声明属性

capture 指定了在可见域范围内 lambda 表达式的代码内可见得外部变量的列表

具体解释如下:
[a,&b] a变量以值的方式呗捕获,b以引用的方式被捕获。
[this] 以值的方式捕获 this 指针。
[&] 以引用的方式捕获所有的外部自动变量。
[=] 以值的方式捕获所有的外部自动变量。
[] 不捕获外部的任何变量。

mutable 修饰符说明 lambda 表达式体内的代码可以修改按值被捕获的变量,并且可以访问被捕获对象的 non-const 方法。

虽然按值捕获的变量值均补复制一份存储在lambda表达式变量中, 修改他们也并不会真正影响到外部,但我们却仍然无法修改它们。

那么如果希望去修改按值捕获的外部变量,需要显示指明lambda表达式为mutable。

需要注意:被mutable修饰的lambda表达式就算没有参数也要写明参数列表。

原因:lambda表达式可以说是就地定义仿函数闭包的“语法糖”。它的捕获列表捕获住的任何外部变量,最终均会变为闭包类型的成员变量。按照C++标准,lambda表达式的operator()默认是const的,一个const成员函数是无法修改成员变量的值的。而mutable的作用,就在于取消operator()的const。
因此,没有捕获变量的lambda表达式(本身的this指针就丢失掉)可以直接转换为函数指针,而捕获变量的lambda表达式则不能转换为函数指针。

int a = 0;  auto f1 = [=] { return a++; };                       //error  auto f2 = [=] () mutable { return a++; };       //OK  

lambda表达式可以认为是一个带有operator()的类,即仿函数,因此我们可以使用std::function和std::bind来存储和操作它

void func(void* arg1){}void* arg;std::function<void()> fn = [arg, func] { func(arg); };
原创粉丝点击