C++11 lambda表达式

本文详细介绍了C++中的lambda表达式,包括其定义、语法、捕获列表、opt选项以及在函数参数中的应用,重点展示了如何通过lambda实现回调功能,如在STL算法中的count_if函数中使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基础语法和概念

lambda表达式定义了一个匿名函数,并且可以捕获一定范围内的变量。
lambda表达式在C++中会被看做是一个仿函数,因此在使用lambda 返回值时要加 () 进行调用。
lambda 表达式的语法形式简单归纳如下:

[capture](params) opt -> ret {body;};

其中 capture 是捕获列表,params是参数列表,opt 是函数选项, ret是返回值类型,body是函数体。

  1. 捕获列表 []:捕获一定范围内的变量
  2. 参数列表 (): 和普通函数的参数列表一样
auto f = [](){return 1;};	// 没有参数, 参数列表为空
auto f = []{return 1;};	// 没有参数, 参数列表省略不写
  1. opt 选项, 可省略
    mutable:可以修改按值传递进来的拷贝(注意是能修改拷贝,而不是值本身),因为按值传递的变量是只读状态,mutable 去掉按值捕获的外部变量的只读(const)属性,使其变得可以修改,而引用传递是可以直接修改值本身,即全局修改。
    exception:指定函数抛出的异常,如抛出整数类型的异常,可以使用throw();
    constexpr:C++17 ,可以指定 lambda 表达式是⼀个常量函数;
  2. 返回值类型:在C++11中,lambda 表达式的返回值是通过返回值后置语法来定义的。
  3. 函数体:函数的实现,这部分不能省略,但函数体可以为空。

lambda 表达式的大致原理:每当你定义⼀个 lambda 表达式后,编译器会自动⽣成⼀个匿名类(这
个类重载了()运算符),我们称为闭包类型(closure type)。
那么在运行时,这个 lambda 表达式就会返回⼀个匿名的闭包实例,其实⼀个右值。所以,lambda 表
达式的结果,本质上就是闭包实例。

捕获列表

  • [] - 不捕捉任何变量
  • [&] - 捕获外部作用域中所有变量, 并作为引用在函数体内使用 (按引用捕获),修改是全局的
  • [=] - 捕获外部作用域中所有变量, 并作为副本在函数体内使用 (按值捕获),由于拷贝的副本在匿名函数体内部是只读的,变量的值为 const 属性,不允许修改
  • [=, &foo] - 按值捕获外部作用域中所有变量, 并按照引用捕获外部变量 foo
  • [bar] - 按值捕获 bar 变量, 同时不捕获其他变量
  • [&bar] - 按引用捕获 bar 变量, 同时不捕获其他变量
  • [this] - 捕获当前类中的this指针(其实是复制指针),可以让 lambda 表达式拥有和当前类成员函数同样的访问权限,如果已经使用了 & 或者 =,则默认添加此选项。
  • [*this] - 通过传值方式捕获当前对象

为什么通过值拷贝的方式捕获的外部变量是只读的:

  1. lambda表达式的类型在C++11中会被看做是一个带 operator() 的类,即仿函数。
  2. 按照C++标准,lambda 表达式的 operator() 默认是 const 的,一个 const 成员函数是无法修改成员变量值的。mutable 选项的作用就在于取消 operator() 的 const 属性。

lambda 表达式⼀个很重要的应用是其可以用于函数的参数,通过这种方式可以实现回调函数。其实,最常用的是在STL算法中,比如你要统计⼀个数组中满足特定条件的元素数量,通过 lambda 表达式给出条件,传递给 count_if 函数:

int val = 3;
vector<int> v {1, 8, 5, 3, 6, 10};
int count = std::count_if(v.beigin(), v.end(), [val](int x) { return x > val; });
// v中⼤于3的元素数ᰁ
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值