Skip to content

Latest commit

 

History

History
158 lines (142 loc) · 4.06 KB

s4.md

File metadata and controls

158 lines (142 loc) · 4.06 KB

lambda表达式

C++11 函数对象的升级版 => lambda表达式 函数对象的使用范围: 使用在泛型算法参数传递,比较性质/自定义操作时都可以。而如果函数对象用于 -> 优先级队列或智能指针 => 构造对象只用在一处使用。此时可以认为你对该函数对象使用频率低。

如果你对该函数对象使用频率较低,仍需构造一个函数对象。不灵活。

于是诞生了lambda表达式

lambda表达式的语法: [捕获外部变量](形参列表)->返回值{操作代码};

如果lambda表达式的返回值(返回值为void)不需要,那么"->返回值"可以省略的。我建议都不省略,尽量写全。

[捕获外部变量]
[]:表示不捕获任何外部变量
[=]:以传值的方式捕获外部的所有变量
[&]:以传引用的方式捕获外部的所有变量
[this]:捕获外部的this指针
[=,&a]:以传值的方式捕获外部的所有变量,但是a变量以传引用的方式捕获
[a, b]:以值传递的方式捕获外部变量a和b
[a, &b]:a以值传递捕获,b以传引用的方式捕获

直接看代码:

#include <iostream>
#include <algorithm>
#include <vector>
#include <functional>
#include <map>
#include <memory>
#include <queue>

using namespace std;
int main()
{
	vector<int> vec;
	for (int i = 0; i < 20; ++i)
	{
		vec.push_back(rand() % 100 + 1);
	}

	sort(vec.begin(), vec.end(), 
		[](int a, int b)->bool
		{
			return a > b; // 从大到小
		});
	for (int val : vec)
	{
		cout << val << " ";
	}
	cout << endl;

	// 65按序插入序列  要找第一个小于65的数字
	auto it = find_if(vec.begin(), vec.end(), 
		[](int a)->bool {return a < 65; });
	if (it != vec.end())
	{
		vec.insert(it, 65);
	}
	for (int val : vec)
	{
		cout << val << " ";
	}
	cout << endl;
	// 当vector中元素为偶数时输出
	for_each(vec.begin(), vec.end(), [](int a)->void
	{
		if(a % 2 == 0)
			cout << a << " ";
	});
	cout << endl;

	return 0;
}

lambda结合stl

#include <iostream>
#include <algorithm>
#include <vector>
#include <functional>
#include <map>
#include <memory>
#include <queue>
using namespace std;

int main()
{
	// 1.lambda表达式存放到map中
	map<int, function<int(int, int)>> caculateMap;
	caculateMap[1] = [](int a, int b)->int {return a + b; };
	caculateMap[2] = [](int a, int b)->int {return a - b; };
	caculateMap[3] = [](int a, int b)->int {return a * b; };
	caculateMap[4] = [](int a, int b)->int {return a / b; };

	cout << "选择:";
	int choice;
	cin >> choice;
	cout << "10 + 15:" << caculateMap[choice](10, 15) << endl;

	// 智能指针自定义删除器   delete p;  FILE*   fclose(FILE*)
	// unique_ptr<FILE> ptr(fopen("data.txt"), "w");
	// 上面需要自定义函数对象进行fclose操作,默认操作是delete
	/*
	unique_ptr<FILE, function<void(FILE*)>> 
		ptr1(fopen("data.txt", "w"), [](FILE *pf)->void {fclose(pf); });
	*/
	return 0;
}

lambda结合function

#include <iostream>
#include <algorithm>
#include <vector>
#include <functional>
#include <map>
#include <memory>
#include <queue>
using namespace std;
/*
既然lambda表达式只能使用在语句当中,如果想跨语句使用之前定义好的lambda表达式,
怎么办?用什么类型来表示lambda表达式?
当然是用function类型来表示函数对象的类型了   bind1st/bind2nd bind绑定器
lambda表达式 => 函数对象   
*/
class Data
{
public:
	Data(int val1 = 10, int val2 = 10) :ma(val1), mb(val2) {}
	//bool operator>(const Data &data)const { return ma > data.ma; } 
	//bool operator<(const Data &data)const { return ma < data.ma; }
	int ma;
	int mb;
};
int main()
{
	// 优先级队列 => 如何划分优先级?Data没办法进行比较的,Data类中指定<和>不方便
	//priority_queue<Data> queue;
	using FUNC = function<bool(Data&, Data&)>; // 相当于重命名function<bool(Data&, Data&)>为FUNC
	priority_queue<Data, vector<Data>, FUNC> maxHeap
	(
		[](Data &d1, Data &d2)->bool
		{
			return d1.mb > d2.mb; // 通过mb成员变量从大到小排序
		}
	);
	maxHeap.push(Data(10, 20));
	maxHeap.push(Data(15, 15));
	maxHeap.push(Data(20, 10));
}