C++11 lambda

转自:https://www.jianshu.com/p/d686ad9de817

lambda表达式最前面的方括号的意义何在?其实这是lambda表达式一个很要的功能,就是闭包。这里我们先讲一下lambda表达式的大致原理:每当你定义一个lambda表达式后,编译器会自动生成一个匿名类(这个类当然重载了()运算符),我们称为闭包类型(closure type)。那么在运行时,这个lambda表达式就会返回一个匿名的闭包实例,其实一个右值。所以,我们上面的lambda表达式的结果就是一个个闭包。闭包的一个强大之处是其可以通过传值或者引用的方式捕捉其封装作用域内的变量,前面的方括号就是用来定义捕捉模式以及变量,我们又将其称为lambda捕捉块。看下面的例子:

int main(int argc, char const *argv[])
{
	
	int x =10;
	auto add_x = [x](int a){return a+x;};

	auto multipy_x = [&x](int a){return a*x;};

	cout<<"add "<<add_x(10)<<" "<<"multipy "<< multipy_x(10)<<endl;


	getchar();
	return 0;
}

lambda捕捉块为空时,表示没有捕捉任何变量。但是上面的add_x是以复制的形式捕捉变量x,而multiply是以引用的方式捕捉x。前面讲过,lambda表达式是产生一个闭包类,那么捕捉是回事?对于复制传值捕捉方式,类中会相应添加对应类型的非静态数据成员。在运行时,会用复制的值初始化这些成员变量,从而生成闭包。

 

捕获的方式可以是引用也可以是复制,但是具体说来会有以下几种情况来捕获其所在作用域中的变量:

  • []:默认不捕获任何变量;
  • [=]:默认以值捕获所有变量;
  • [&]:默认以引用捕获所有变量;
  • [x]:仅以值捕获x,其它变量不捕获;
  • [&x]:仅以引用捕获x,其它变量不捕获;
  • [=, &x]:默认以值捕获所有变量,但是x是例外,通过引用捕获;
  • [&, x]:默认以引用捕获所有变量,但是x是例外,通过值捕获;
  • [this]:通过引用捕获当前对象(其实是复制指针);
  • [*this]:通过传值方式捕获当前对象;



 

### C++11 Lambda 表达式简介 C++11 中引入了 lambda 表达式这一强大特性,使得开发者能够更加便捷地定义和创建匿名函数[^1]。这种新的编程工具不仅简化了代码编写过程,还提高了程序的功能性和执行效率。 ### 声明 Lambda 表达式 Lambda 表达式的通用形式如下: ```cpp [capture list] (parameters) -> return_type { // function body } ``` 其中 `capture list` 是捕获外部变量的方式列表,`(parameters)` 定义参数表,而 `-> return_type` 可选指定返回类型[^2]。 ### 捕获列表详解 捕获列表决定了哪些局部变量可以在 lambda 函数体内被访问以及如何访问它们。常见的几种方式有: - **空捕获列表**:不捕获任何外部变量。 ```cpp [] () { /* ... */ } ``` - **按值捕获所有可见局部变量**:使用 `[=]` 符号表示将当前作用域内的所有局部变量复制到闭包对象中。 ```cpp [=] () { /* can use local variables by value */ } ``` - **按引用捕获所有可见局部变量**:通过 `[&]` 来实现对外部变量的引用传递。 ```cpp [&] () { /* can modify and read local variables directly */ } ``` - **混合模式**:允许同时存在按值和按引用两种类型的捕获操作。 ```cpp [=, &var] () { /* var is captured as reference while others are copied */ } ``` ### 实际应用案例 考虑一段具体的例子来展示不同情况下 lambda 的实际运用情况: ```cpp #include <iostream> using namespace std; int main() { int a = 1; int b = 2; // 创建一个简单的加法器 auto adder = [a, b]() { return a + b; }; cout << "Simple addition result: " << adder() << endl; // 修改其中一个被捕获变量并观察变化 auto modifier = [&b](int increment) { b += increment; }; modifier(5); cout << "Modified variable 'b': " << b << endl; // 结合多个参数计算总和 int c = 3; auto sumAll = [&](int d){ return a + b + c + d; }; cout << "Sum of all numbers: " << sumAll(4) << endl; return 0; } ``` 这段代码展示了三种不同的场景下 lambda 表达式的具体用法及其效果[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值