C++11_lambda表达式


一、lambda表达式

lambda表达式是C++11新引入的功能,它的用法与我们之前学过的C++语法有些不同。

1.lambda的组成

[capture-list] (parameters) mutable -> return-type { statement }

[capture-list] : 捕捉列表,该列表总是出现在lambda函数的开始位置,编译器根据[]来
判断接下来的代码是否为lambda函数,捕捉列表能够捕捉上下文中的变量供lambda
函数使用。
(parameters):参数列表。与普通函数的参数列表一致,如果不需要参数传递,则可以
连同()一起省略
mutable:默认情况下,lambda函数总是一个const函数,mutable可以取消其常量
性。使用该修饰符时,参数列表不可省略(即使参数为空)。
->returntype:返回值类型。用追踪返回类型形式声明函数的返回值类型,没有返回值时此部分可省略。返回值类型明确情况下,也可省略,由编译器对返回类型进行推
导。
{statement}:函数体。在该函数体内,除了可以使用其参数外,还可以使用所有捕获到的变量

示例代码如下

	int a = 2;
	int b = 3;
	auto func1 = [](int a, int b)->int {
		return a + b;
		};
	std::cout << func1(a, b) << std::endl;

首先看示例代码
“[capture-list]”: 下面再讲,这里需要记住是[]即便里面没有内容也不可以省略。
“(parameters)” :很像我们函数的参数列表,而实际上在这里的作用也是如此。如果没有参数,那么可以连同()一起省略
“->returntype” :->返回值类型,一般都可以省略,但是推荐不省略。
“{}”: 可以理解为函数体,内部写自己想实现的功能。


示例代码如下

	int a = 2;
	int b = 3;
	auto func1 = [a, b]()->int {
		++a;  编译报错
		++b;  编译报错
		return a + b;
	};
	
	auto func2 = [a, b]()mutable->int {
		++a;   运行通过
		++b;
		return a + b;
	};
	func2(); //调用func2
	std::cout << " func2: " << a << " - " << b << std::endl;

“[capture-list]”: 捕捉的是现有变量让它们能在函数体内运行。
func1 和 func2 唯一的区别就是有没有加mutable(可变的)。默认情况下,lambda函数总是一个const函数,mutable可以取消其常量
性。 所以func2使用mutable就可以改变函数体内a和b的值。

那么这里提出疑问,外面的a和b的值是否被修改? -> 不会
在这里插入图片描述

因为这里其实是一个传值拷贝,如果你需要在lambda内部改变外面的a,b,可以使用引用

	int a = 2;
	int b = 3;
	
	auto func1 = [a, b]()mutable->int {
		++a;
		++b;
		return a + b;
		};
	func1(); //调用func1
	std::cout << " func1: " << a << " - " << b << std::endl;

	auto func2 = [&a, &b]()mutable->int {
		++a;
		++b;
		return a + b;
		};
	func2(); //调用func2
	std::cout << " func2: " << a << " - " << b << std::endl;

在这里插入图片描述

2.[capture-list] 的其他使用方法

“[=]”:根据上下文全部以值传递捕捉变量
"[&]':根据上下文全部以引用传递捕捉变量

	int a = 1;
	int b = 2;
	double d = 2.2;
	std::string str = "hello world";

	auto func1 = [=]()mutable {  //根据上下文全部以值传递捕捉变量
		std::cout << a << " " << b << " " << d << " " << str << std::endl;
		a = 10;
		};
	func1();
	std::cout << "a: " << a << std::endl << std::endl;;

	auto func2 = [&]()mutable {  //根据上下文全部以引用传递捕捉变量
		std::cout << a << " " << b << " " << d << " " << str << std::endl;
		a = 10;
		};
	func2();
	std::cout << "a: " << a << std::endl;
	

在这里插入图片描述


2.1混合捕捉

	int a = 1;
	int b = 2;
	double d = 2.2;
	std::string str = "hello world";

	auto func1 = [= , &a]()mutable{//除a以引用传递捕捉,其他根据上下文全部以值传递捕捉变量
		std::cout << a << " " << b << " " << d << " " << str << std::endl;
		a = 10;
		};
	func1();
	std::cout << "a: " << a << std::endl << std::endl;;

	auto func2 = [&, a]()mutable{//除a以值传递捕捉,其他根据上下文全部以引用传递捕捉变量
		std::cout << a << " " << b << " " << d << " " << str << std::endl;
		a = 1;
		};
	func2();
	std::cout << "a: " << a << std::endl;


在这里插入图片描述

二、lambda表达式的使用场景

1.替代仿函数

仿函数我们之前对于实现很多STL中的容器的排序都使用过,应该不陌生,而lambda表达式我们看来其实也跟一个函数差不多,一样有参数,一样有返回值,一样能写函数体,所以我们就可以使用lambda来取代仿函数

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<functional>
struct Goods {

	Goods(std::string name, double price, size_t evaluation)
		:_name(name)
		,_price(price)
		,_evaluation(evaluation) {}

	std::string _name;
	double _price;
	size_t _evaluation;
};

int main()
{
	std::vector<Goods> v = {{ "苹果", 2.1, 5 },{ "香蕉", 3, 4 }, 
						{ "橙子", 2.2, 3 },{ "菠萝",1.5,4 }};


	std::sort(v.begin(), v.end(), [](const Goods& s1, const Goods& s2)->bool {
	return s1._name < s2._name;
	}); // 字符串升序
	for (auto& a : v)
	{
		std::cout << a._name << " - " << a._price << " - " << 	a._evaluation << std::endl;
	}
	std::cout << std::endl;


	std::sort(v.begin(), v.end(), [](const Goods& s1, const Goods& s2)->bool {
	return s1._name > s2._name;
	}); // 字符串降序
	for (auto& a : v)
	{
		std::cout << a._name << " - " << a._price << " - " << a._evaluation << std::endl;
	}
	std::cout << std::endl;


	std::sort(v.begin(), v.end(), [](const Goods& s1, const Goods& s2)->bool {
	return s1._price < s2._price;
	}); // 价格升序
	for (auto& a : v)
	{
	std::cout << a._name << " - " << a._price << " - " << a._evaluation << std::endl;
	}
	std::cout << std::endl;


	std::sort(v.begin(), v.end(), [](const Goods& s1, const Goods& s2)->bool {
		return s1._evaluation < s2._evaluation;
		}); // 评价升序
	for (auto& a : v)
	{
		std::cout << a._name << " - " << a._price << " - " << a._evaluation << std::endl;
	}
	std::cout << std::endl;

	return 0;
}

在这里插入图片描述

总结

这些就是lambda表达式的全部内容,lambda表达式还是十分有用的,对于一些我们只需要运行一遍的函数或者是对象内传仿函数类型,我们都可以使用使用lambda表达式。

  • 28
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Lambda表达式是C++11引入的一种函数对象,可以在需要函数对象的地方使用,比如作为函数参数、返回值等。Lambda表达式的语法形式如下: ``` [capture list](parameters) mutable exception -> return type { // function body } ``` 其中,`capture list` 表示捕获列表,用于捕获外部变量。`parameters` 表示函数参数列表,`mutable` 用于表示是否可以修改值传递的变量,`exception` 是异常列表,`return type` 表示返回类型,`function body` 则是函数体。 在Lambda表达式中,可以通过 `[this]` 捕获当前对象的指针,即 `this` 指针,可以方便地访问当前对象的成员变量和成员函数。例如: ``` class MyClass { public: void foo() { int x = 1; auto lambda = [this, x]() mutable { this->m_member_var += x; this->m_member_function(); x++; }; lambda(); } private: int m_member_var; void m_member_function(); }; ``` 在上面的例子中,Lambda表达式通过 `[this, x]` 捕获了当前对象的指针和 `foo()` 函数中定义的变量 `x`。在 Lambda 表达式中可以通过 `this->m_member_var` 和 `this->m_member_function()` 访问当前对象的成员变量和成员函数。由于 `x` 是值传递的,所以在 Lambda 表达式中需要使用 `mutable` 关键字使其可修改,可以通过 `x++` 修改变量的值。最后调用 `lambda()` 执行 Lambda 表达式。 需要注意的是,Lambda表达式捕获 `this` 指针时,需要保证当前对象是有效的,即不能在已经销毁的对象中访问成员变量和成员函数。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

风君子吖

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

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

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

打赏作者

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

抵扣说明:

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

余额充值