C++11中的lambda匿名函数

一、引言

        C++11中引入的lambda表达式(也称为匿名函数或lambda函数)提供了一种方便且灵活的方式来定义和使用小的匿名函数对象。这些lambda表达式在编写回调函数、操作容器的算法中、或者在需要快速定义和传递一个函数逻辑给另一个函数时特别有用。

二、基本语法

[capture](parameters) mutable -> return_type {  
    // 函数体  
}
  • capture:对lambda函数外部变量的捕获方式:
lambda匿名函数捕获外部变量的方式
表示方式说明
[ ]不捕获任何外部变量
[=]值传递的方式捕获全部外部变量
[&]引用传递的方式捕获全部外部变量
[&x, y]x以引用传递的方式捕获,y以传值的方式捕获
  • parameters:函数的参数列表
  • mutable:是否可以修改以值传递的外部变量,加上mutable表示可以修改,否则不能修改
  • return_type:函数的返回类型,省略时,返回类型就是函数内return语句返回值的类型。

说明:全局变量会自动进行引用捕获。

三、外部变量的捕获

1. 不捕获任何外部变量

int main(){
	
	auto fun = [](int a, int b)->int{
		return a + b;
	};
	
	int sum = fun(1, 2);
	
	cout << sum << endl;  // 输出3
	
	return 0;
}

2. 访问全局变量

int x = 10;    // 全局变量

int main(){	
	auto fun = [](){
		++x;    // 自动捕获全局变量 x
	};
	
	cout << x << endl;    // 输出10
	
	fun();
	
	cout << x << endl;    // 输出11
	
	return 0;
} 

3. 传值捕获所有外部变量

int main(){	
	int x = 10;
	int y = 20;
	auto fun = [=]()->int{
		// x++;  //不可以修改x的值,x在lambda内是const的 
		return x + y;    // x得到30
	};
	
	int sum = fun();
	cout << sum << endl;
	
	return 0;
} 

输出内容: 

         从输出的地址可以知道,lambda函数内的变量x与函数外的变量x不是同一个变量,只是用外部x变量的值初始化了函数内的x变量(相当于传值的形参)。并且不能修改x的值,因为x是const的。如果想要修改x的值,可以使用mutable关键字修饰lambda函数。

4. 以引用的方式捕获所有的外部变量

int main(){	
	int x = 10;
	int y = 20;
	cout << (&x) << endl;
	auto fun = [&]()->int{
		x++;  //以引用方式捕获的变量可以修改其值
		cout << (&x) << endl; 
		return x + y;
	};
	
	int sum = fun();
	cout << sum << endl;
	
	return 0;
}

输出内容:

        从输出的地址可以知道,lambda函数内的变量x与函数外的变量x是同一个变量(地址相同)。 

5. 混合捕获

int main(){	
	int x = 10;
	int y = 20;
	cout << (&x) << endl;
	auto fun = [&x, y]()mutable{
		x++;  // 可以修改x的值,修改的是函数外的x变量 
		y++;  // y以传值捕获,因为函数声明为mutable,所有y可以修改,修改的是lambda内部的y 
		cout << (&x) << endl; 
		return x + y;
	};
	
	int sum = fun();
	cout << sum << endl;
	cout << "x = " << x << ", y = " << y << endl;
	
	return 0;
} 

输出内容:

         x以引用传递,y以值传递,所以在lambda函数内修改的x是函数外的x,而y则是lambda函数内的y,与函数外的y不是同一个变量。

四、参数示例

        lambda函数的参数和普通函数是一样的,可以有传值、传地址和传引用几种方式。

1. 传值

int main(){	
	int x = 10;
	int y = 20;
	cout << (&x) << endl;
	auto fun = [](int x, int y){
		x++;  // 可以修改形参x的值
		y++;  // 可以修改形参y的值 
		cout << (&x) << endl; 
		return x + y;
	};
	
	int sum = fun(x, y);
	cout << sum << endl;
	// lambda函数外的x和y没有被修改 
	cout << "x = " << x << ", y = " << y << endl;
	
	return 0;
} 

2. 传地址

int main(){	
	int x = 10;
	int y = 20;
	auto fun = [](int *x, int *y){
		(*x)++;  
		(*y)++;  
		return (*x) + (*y);
	};
	
	int sum = fun(&x, &y);
	cout << sum << endl;
	// x = 11, y = 21 
	cout << "x = " << x << ", y = " << y << endl;
	
	return 0;
} 

3. 传引用

int main(){	
	int x = 10;
	int y = 20;
	auto fun = [](int &x, int &y){
		x++;  
		y++;  
		return x + y;
	};
	
	int sum = fun(x, y);
	cout << sum << endl;
	// x = 11, y = 21 
	cout << "x = " << x << ", y = " << y << endl;
	
	return 0;
} 

六、常用场合

1. 临时函数

// lambda表达式
#include <iostream>
#include <cstdlib>
using namespace std;

int main() {
	int arr[]{4,1,8,5,2};
	qsort(arr, sizeof(arr)/sizeof(arr[0]), sizeof(arr[0]), 
		[](const void *p1, const void *p2){
			int a = *((int*)p1);
			int b = *((int*)p2);
			return a == b ? 0 : (a < b ? 1 : -1);
		});
	
	for (int i: arr){
		cout << i << "  ";
	}  // 降序排列,输出8 5 4 2 1

	return 0;
}

2. STL算法中

#include <iostream>  
#include <vector>  
#include <algorithm>  
  
int main() {  
    std::vector<int> numbers = {1, 2, 3, 4, 5};  
  
    // 使用lambda表达式对vector中的每个元素加1  
    std::for_each(numbers.begin(), numbers.end(), [](int& n) { n += 1; });  
  
    // 打印结果  
    for(int n : numbers) {  
        std::cout << n << ' ';  
    }  
    std::cout << '\n';  
  
    return 0;  
}

七、注意事项


        Lambda表达式产生的对象类型是唯一的匿名非联合非聚合类类型,称为闭包类型。
捕获的变量(如果是引用捕获)在lambda函数体之外的生命周期结束时,引用可能变为悬空引用,使用时需要特别注意。
Lambda表达式中的this指针在捕获列表中自动处理,如果使用[&]或[=]捕获方式,则this指针会被捕获。如果要显式捕获this,可以在捕获列表中包含*this或this(视具体需求而定)。

八、小结


        C++11中的lambda表达式是C++编程中一个非常强大的特性,极大地增强了代码的灵活性和表达能力。同时增强了函数式编程的能力。

附:c++11新增的其他性

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hn_tzy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值