c++ functional之匿名函数捕获子句

匿名函数是一个非常方便的函数,
他可以不需要函数的名字自己被函数指针,或被当成参数传递给高阶函数调用,或者直接输出函数指针
函数对象
回调函数
function和bind

#include <iostream>
#include <vector>
using namespace std;
// Lambda 表达式 类似于函数 但不需要函数名 因此成为匿名函数

int accumulate(vector<int>arr, int n, int(*fun)(int)) {
	int sum{ 0 };
	for (int i = 0; i != n; i++)
		sum += fun(arr[i]);	//直接调用没函数体 把(i) 传递到[](int x)中 []匿名函数
	return sum;
}
int Abs(int x) { return abs(x); }
int square(int x) { return x * x; }
int main() {
	vector<int>a{ 3,5,7,9 };
	auto pf = accumulate; // int (*pf)(vector<int>arr, int n, int(*fun)(int))
	cout << pf(a, a.size(), Abs) << endl;
	cout << pf(a, a.size(), square) << endl;
 	cout << pf(a, a.size(), [](int x) {return x * x * x; }) << endl;
	while (true);
	return 0;
}

//int accumulate(vector<int>arr, int n, int(*fun)(int)) {
//	int sum{ 0 };
//	for (int i = 0; i != n; i++)
//		sum += [](int x) {return x * x; }(i);	//直接调用没函数体 把(i) 传递到[](int x)中 []匿名函数
//	return sum;
//}

匿名函数中的捕获子句 实际就是[]括号里面的参数可以通过传递或者引用的方式
拿到在匿名函数中使用
捕获子句 就是在匿名函数里面的[a]来捕获 其中 = 捕获子句表示 Lambda 包围的环境 即main()所以变量如v a都可以直接访问
=捕获子句 使得局部环境中的变量是通过传递的方式给Lambda函数的 即这些变量被复制到Lambda表达式中
&是将环境中的变量以引用的方式传递给Lambda表达式,也就是说可以直接引用包围环境中的变量
但是[=,&]不能同时包含 还有=或& 必须是第一项[&,a][=,&a] 不能写成[a,=]

#include <iostream>
#include <vector>
using namespace std;
template<typename T>
class X {
public:
	X(double x):value{x}{}
	double find_nearest(const vector<double>arr, const int n) { // 函数参数后面 {}前面加->type 就是说明返回类型 通常是匿名函数用
		return find_optimal(arr, n, [this](double a, double b)->double { // [value] 会报错因为 lambda 试图捕获该类的成员变量value 但是他属于一个类对象而不属于整个类
			return abs(a - this->value) < abs(b - this->value);		// 所以要用this
			});
	}
private:
	double value{ 0. };
};

template<typename T, typename CompareT>  // CompareT 接受所有类型 下面丢的一个匿名函数 两个函数
T find_optimal(const vector<T>arr, const int n, CompareT compare) { //这个模板带了两个参数一个匿名函数
	T opt{ arr[0] };
	for (auto i = 1; i != n; i++)
		if (compare(arr[i], opt)) //arr[i] 比opt更好 arr[i] 在遍历比较
			opt = arr[i];
	return opt;
}
int main() {
	vector<double>a{ 7,1,5,9 };
	int count = 0; double v;
	cin >> v;
	cout << find_optimal(a, a.size(), [&](double x, double y) { //这个匿名函数& 就是引用局部变量的所有值
		a[count] -= v; // 修改了a的值
		count++;	
		return abs(x - v) < abs(y - v);
		});
	cout << "\t比较次数:" << count << endl;
	cout << "修改了的a值";
	for (auto e : a)
		cout << e << "\t";
	cout << endl;
	cout << find_optimal(a, a.size(), [&count,v](double x, double y) { // 引用了count的地址v是传递过来的
		//[=,&count] 表示其他局部变量都是传递过来的 count是引用的
		//[&,count] 表示其他局部变量都是引用过来的 count是传递过来的
		//a[count] -= v; 因为上面捕获的只有count和v 单独捕获 所以不能修改a
		count++;
		return abs(x - v) < abs(y - v);
		});
	cout << endl;
	X<double>x(v);
	cout << x.find_nearest(a, a.size())<<endl;
	while (true);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值