c++11:lambda表达式

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  
auto f2 = [&] { return a++; };          //OK 

auto f = [=] {return a};
a += 1;
cout<<f()<<endl; //输出结果为0;

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

void func(void* arg1){}
void* arg;
std::function<void()> fn = [arg, func] { func(arg); };
  #include <iostream>
  #include <functional>

  using namespace std;


  class A
  {
      public:
      void H() {}//看着是无参,其实第一个参数是this指针

  };

  void Fun(A a)
  {

  }

  int main()
  {
      int i = 8;
      std::function<void()> fn = [i]()mutable { i++;  };  
      cout<<i<<endl;
      typedef void (*Ptr)(int);
   //   Ptr p = [&](int p){cout<<p<<endl;cout<<i<<endl;};
      Ptr p = [](int p){cout<<p<<endl;};                                                                                                                                                                                        
      p(9);
      std::function<void(int)> ptr = [&](int p){cout<<p<<endl;cout<<i<<endl;};
      ptr(8);
      A a;
      std::function<void()> f_1 = std::bind(&A::H, a); 
      std::function<void()> f_2 = std::bind(Fun, a); 
      std::function<void()> f_3 = [a]()mutable{a.H();};
      return 0;
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值