Lambda表达式

在C++中,一共有四种可调用对象:函数、函数指针、重载了函数调用运算符的类以及Lambda表达式。

   对Lambda的总结如下:

    一个Lambda表达式就是一个可调用的代码单元,也相当于一个未命名的内联函数,一个lambda表达式的标准形式:

      

可以忽略参数列表和返回类型,但是必须包含捕获列表和函数体,调用方式与普通函数相同。

auto fun=[ ]{return  42};

cout<<fun()<<endl;//输出42

参数列表为空,忽略返回类型时,根据函数体推断返回类型,如果函数体中只有一个return语句,则根据返回表达式类型推断,否则,返回类型为void

(1)向lambda传递参数

[ ](const string& a,const string& b) { return a.size()>b.size();}

捕获列表也就是[ ]为空时,说明不使用所在函数的任何局部变量,当需要使用所在函数的局部变量时,则需要放在捕获列表内

例如:void find(){

int sz=10;

auto wc=find_if(words.begin(),words.end(),[sz] (const string &a ) { return a.size()>=sz;} );

}

lambda中使用了所在函数中定义的局部(非static)变量sz,则必须放进捕获列表中,否则出错。

lambda可以直接使用定义在当前函数之外的名字。

(2)捕获和返回

lambda 有两种捕获方式: 显式捕获以及隐式捕获,其中 显式捕获又包括值捕获和引用捕获。lambda的数据成员在lambda对象创建时被初始化。

(2.1) 显式捕获

值捕获

例如:void f1(){

size_t  v1=1;

auto f=[v1] {return v1;}

v1=0;

auto j=f();//此时j等于1 ,f保存了创建对象时v1的拷贝

}

 引用捕获

例如:void f1(){

size_t  v1=1;

auto f=[&v1] {return v1;}

v1=0;

auto j=f();//此时j等于0 ,f保存了v1的引用

}

使用引用捕获时,必须保证被引用的对象在lambda执行的时候是存在的,因为引用必须初始化。

可以从函数中返回一个lambda,但是不能包含引用捕获,因为这相当于函数返回了一个局部变量的引用。


(2.2)隐式捕获

在捕获列表中写一个& 表示引用捕获,写一个=表示值捕获

例如:

void find(){

int sz=10;

auto wc=find_if(words.begin(),words.end(),[=] (const string &a ) { return a.size()>=sz;} );

}

sz采用隐式捕获,值捕获的方式。


隐式捕获与显式捕获可以混合使用,例如:


当混合使用时,捕获列表中的第一个元素必须是&或者=,指定了默认的捕获方式,不采用默认的话,就必须显式捕获方式命名变量。


(3)可变lambda:

对于值捕获方式,默认lambda不会改变其值,如果想改变的话,在参数列表后加上关键字mutable。

例如:void f1(){

size_t  v1=1;

auto f=[v1] ()mutable {return ++v1;}

v1=0;

auto j=f();//此时j等于2

}

而对于引用捕获的方式,变量能否修改则依赖于引用指向的是const类型还是非const类型。


(4)指定lambda的返回类型

 lambda函数体内除了return语句还有其他语句,默认返回void,如果想要指定返回值类型,在参数列表后加 ->+类型。

例如:

transform(vi.begin(),vi.end(),[ ](int i){return i<0? -i:i;});

该lambda返回一个int值,但是此时因为函数体只有return语句,所以无须指定返回类型,类型可以推断出来

transform(vi.begin(),vi.end(),[ ](int i){if(i<0) return -i;else return i;});

此时由于函数体内还有其他语句,所以不能推断返回类型,编译错误,必须指定返回类型:

transform(vi.begin(),vi.end(),[ ](int i) -> int {if(i<0)return -i;else return i;});

捕获列表为空,接受单一int参数,返回一个int值,必须指定返回类型。
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值