C++lambda 捕获

lambda相当于一个匿名函数一样使用
但是它并非是匿名函数,编译器会为我们生成一个类,lambda的类,如果用auto接实际上返回的是一个函数对象
我们今天详细讲一下lambda的捕获

#include<iostream>
class Demo {
public:
	Demo(int i):m(i){}
	void operator()() {
		[this] {std::cout << m << std::endl; }();
	}
	void demo(int a) {
		[=,this] { this->m = a; }();//有所不同的是只需要this就可以修改成员变量的值了
	}
	void test() {
		[this] {this->m = 111; }();	//其实加不jia=都可以直接改变成员变量,但是没用=捕获的话没办法获取传入的值,不能像上面那样
	}
private:
	int m = 0;
};
int main() {

	//当不接收参数的时候可以省略(),最后加上()是为了调用,下面这些产生的结果是一样的,至少在目前是的
	std::cout << [] { return 5; }() << std::endl;

	std::cout << []()->decltype(auto) {return 5; }() << std::endl;

	std::cout << []()->int {return 5; }() << std::endl;

	std::cout << []()->auto {return 5; }() << std::endl;


	int a = 0;
	//或者接收参数
	auto p = [](int b) {std::cout << b << std::endl; };
	p(a);
	auto p2 = [](auto b) {std::cout << b << std::endl; };
	p2(a);


	//或者直接捕获 下面的区别无非是捕获整个作用域和捕获具体的变量
	[=] {std::cout << a << std::endl; }();
	[i = a] {std::cout << i << std::endl; }();

	//或者直接修改
	[&] {a = 100; std::cout << a << std::endl; }();

	[&a] {a = 100; std::cout << a << std::endl; }();

	[ca=std::as_const(a)] ()mutable {ca = 10; std::cout << ca << std::endl; }();
	std::cout << a << std::endl;

	//下面这是在类内的捕获情况
	Demo demo(10);

	demo();

	demo.demo(123);

	demo();

	demo.test();//这种方式是无法改变成员变量的值的

	demo();


	//其实还有很多操作,最后补充一下,可以像下面这样
	int e(0), f(0), g(0);
	[E = e, F = f, G = g] {std::cout << E << ' ' << F << ' ' << G << std::endl; }();

	[&E = e, &F = f, &G = g] {E = 1, F = 2, G = 3; std::cout << E << ' ' << F << ' ' << G << std::endl; }();
	std::cout << e << ' ' << f << ' ' << g << std::endl;
	
	//另外,不省略()然后->指定类型啥的其实都行,如果是引用捕获的时候()mutable的话也合法,虽然没啥区别,先这样,语法糖而已
	return 0;
}

我们顺便再提一下C++14提出的可以在lambda内使用auto
简单的说就是能给lambda的形参类型写成auto演示如下

#include<iostream>
#include<string>
#include<array>
#include<algorithms>
/*在C++14 中引入的泛型lambdas,是一种成员模板的简化。对于一个简单的计算两个任意类
型参数之和的lambda:*/

/*
[](auto x, auto y) {
	return x + y;
}
*/
//编译器会默认为它构造下面这样一个类:
class SomeCompilerSpecificName {
public:
	SomeCompilerSpecificName(){}; // 构造函数只能由编译器调用
		template<typename T1, typename T2>
	auto operator() (T1 x, T2 y) const {
		return x + y;
	}
};
int main()
{
	int x = 2;
	double y = 3.2,i=3.4;
	auto fool = [=](auto x, auto y) {return x + y; };
	std::cout << typeid(fool).name() << std::endl;
	std::cout << fool(x, y) << std::endl;//5
	std::cout << fool(x, i) << std::endl;//5.4
	return 0;
}
//下面是一个实际使用的例子
void test01() {
	std::array<std::string, 2>str{ "111","222" };
	std::for_each(std::begin(str), std::end(str), [](auto i) {std::cout << i << ","; });
}
void test02() {
	int num[5]{ 1,2,3,4,5 };
	std::for_each(std::begin(num), std::end(num), [](auto i) {std::cout << i << ","; });
}
int main()
{
	test01();
	test02();
	return 0;
}

关于泛型lambda,它的原理我们就先不介绍了,会用即可,说起来也麻烦
如果感兴趣的话可以看看我详细写的文章


视频讲解

还是很简单的 多用即可

如果还想深入了解可以看博主的几篇别的lambda文章,比如https://blog.csdn.net/a4364634611/article/details/127865918

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值