lambda表达式(自 C++11 起)

lambda表达式(自 C++11 起)

功能

​ 构造闭包:构造一个未命名的函数对象,能够捕获作用域中的变量。

​ 闭包(匿名函数):能够读取其他函数内部变量的函数。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。

​ 用于替代一些功能比较简单,但又有大量使用的函数,可以使用lambda搭配STL算法如sort(),genrate()等函数,来实现想要的效果。

语法

[ 捕获 ] ( 参数列表 ) 说明符 -> 返回类型 { 函数体; };

捕获

​ 获取当前作用域中的变量。捕获是零个或多个捕获的逗号分隔列表,可以选择以捕获默认值开头。捕获列表定义了可从 lambda 函数体内部访问的外部变量。

​ 捕获的方式为:

  • &(通过引用隐式捕获使用的自动变量)
  • =(通过复制隐式捕获使用的自动变量)
捕获方式说明
[]默认不捕获任何变量
[=]默认以复制捕获所有变量
[&]默认以引用捕获所有变量
[x]仅以复制捕获x,其它变量不捕获
[x…]以包展开方式复制捕获参数包变量
[&x]仅以引用捕获x,其它变量不捕获
[&x…]以包展开方式引用捕获参数包变量
[=, &x]默认以复制捕获所有变量,但是x是例外,通过引用捕获
[&, x]默认以引用捕获所有变量,但是x是例外,通过复制捕获
[this]通过引用捕获当前对象(其实是复制指针)(C++20起)
[*this]通过复制方式捕获当前对象(C++17 起

参数列表

​ 默认为空,与普通函数传参方式相同

说明符

​ 如果未提供,则副本捕获的对象在 lambda 主体中是 const。在每个序列中,最多允许使用一次说明符:

  • mutable:允许函数体修改由 copy 捕获的对象,并调用其非 const 成员函数。当lambda要修改值捕获的变量时,必须添加mutable声明。

返回类型

​ lambda的返回类型。lambda会自动推断返回值类型,也可以显示指明返回类型。

函数体

​ 和普通函数函数体相同。

示例

  1. 使用lambda定义一个普通匿名函数,使用auto自动推断变量类型(lambda函数类型唯一)
auto lambdaTest= []() {std::cout << "This is a lambda test." << std::endl;};
lambdaTest();
  1. 使用值传递x,使用引用传递y,lambda自动推断返回值。
int y=1;
double x=2.5;
auto lambdaTest= [x, &y]() {
    //x++; 报错,x为只读
    y++;
    std::cout << x << "+" << y << "=" << x+y << std::endl;
    return x+y;
};
std::cout<< lambdaTest() <<std::endl;
std::cout<< y <<std::endl;  // y值改变
  1. 自动推断返回类型,mutable关键字使得值传递变量可修改,它的修改出了lambda表达式以后就无效了。
double x=2.5;
int y = 1;
auto lambdaTest = [y, &x] (double a, int b) mutable  { 

    y = y+2;    //y值在此作用域内可改变,因为mutable关键字
    x = x+5;
    std::cout << x << " "<< y << std::endl; // 7.5 3
    return a + b + x;
};

std::cout<< lambdaTest(1.3, 2) <<std::endl; // 10.8
std::cout<< x << " " << y <<std::endl;  // 7.5 1 ;x值改变, y值不改变
  1. 指定返回类型,使用值传递所有参数(x例外,为引用传递)
double x=2.5;
int y = 1,z=2;
auto lambdaTest = [=, &x] (double a, int b) mutable->int  { 
	z++; //不报错
    x = x+5;
    std::cout << x+y+z  << std::endl; // 11.5
    return a + b + x;
};
std::cout<< lambdaTest(1.3, 2) <<std::endl; // 10 ;类型转换
  1. 与sort()配合使用,实现根据数据第二个数从小到大排序。
vector< vector<int> > v_test = { {0,1},{3,5}, {2,3} , {4,0} };
sort(v_test.begin(),v_test.end(),[](vector<int>&a, vector<int>&b){return a[1]<b[1];});
for(auto &x:v_test)
{
	std::cout << x[0] << " "<< x[1]<<endl; //输出结果
}

Tips

  • lambda无法捕获任何具有静态存储持续时间的变量
  • auto lambdaTest= [=,x]{return 1;} ; //错误,使用了值传递后面不能重复使用
  • auto lambdaTest= [&,&x]{return 1;}; //错误,使用了引用传递后面不能重复使用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值