1、lambda表达式(本质是匿名函数)

格式:

[capture_list](parameters)mutable->return_type(statement)
  • 1.

包装器_匿名函数

[]捕捉列表任何情况下都不能省略

包装器_匿名函数_02

包装器_仿函数_03

对于我们来说lambda是匿名函数,但对于编译器来说其实不是匿名函数

包装器_匿名函数_04

为lambda+ uuid

使用场景:类类型比大小的标准

struct Compare1
{
	bool operator()(const Goods& gl, const Goods& gr)
	{
		return gl._price < gr._price;
	}
};

struct Compare2
{
	bool operator()(const Goods& gl, const Goods& gr)
	{
		return gl._price > gr._price;
	}
};

//int main()
//{
//	vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2,
//3 }, { "菠萝", 1.5, 4 } };
//
//	sort(v.begin(), v.end(), Compare1());
//	sort(v.begin(), v.end(), Compare2());
//
//	// 价格升序
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2)->bool
//		{
//			return g1._price < g2._price;
//		});
//
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2)->bool
//		{
//			return g1._price > g2._price;
//		});
//
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2)->bool
//		{
//			return g1._evaluate < g2._evaluate;
//		});
//
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2)->bool
//		{
//			return g1._evaluate > g2._evaluate;
//		});
//
//
//	return 0;
//}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.

传值捕捉相当于拷贝并用const修饰,mutable可使const失效,但修改捕捉对象并不影响外面捕捉对象的值,因为这只是一种拷贝

int main()
{
	int a = 0, b = 1;

	auto swap1 = [](int& x, int& y)
	{
		// 只能用当前lambda局部域和捕捉的对象
		int tmp = x;
		x = y;
		y = tmp;
	};

	swap1(a, b);

	// 传值捕捉本质是一种拷贝,并且const修饰了
	// mutable相当于去掉const属性,可以修改了
	// 但是修改了不会影响外面被捕捉的值,因为是一种拷贝
	auto swap2 = [a, b]()mutable
	{
		int tmp = a;
		a = b;
		b = tmp;
	};

	swap2();

	auto swap3 = [&a, &b]()
	{
		int tmp = a;
		a = b;
		b = tmp;
	};

	swap3();

	return 0;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.

2、function(包装可调用对象)

对象:函数指针对象

          仿函数对象

          lambda对象

格式

function<返回类型(参数类型)>xxx包装名 = 包装的对象
  • 1.

案例一

#include<functional>

int f(int a, int b)
{
	return a + b;
}

struct Functor
{
public:
	int operator() (int a, int b)
	{
		return a + b;
	}
};


/
// 包装可调用对象
function<int(int, int)> f1 = f;
function<int(int, int)> f2 = Functor();
function<int(int, int)> f3 = [](int a, int b) {return a + b; };
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.

案例二:

class Plus
{
public:
	static int plusi(int a, int b)
	{
		return a + b;
	}

	double plusd(double a, double b)
	{
		return a + b;
	}
};
//
// 包装静态成员函数
function<int(int, int)> f4 = &Plus::plusi;
cout << f4(1, 1) << endl;

// 包装非静态成员函数
function<double(Plus*, double, double)> f5 = &Plus::plusd;
Plus pd;
cout << f5(&pd, 1.1, 1.1) << endl;
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.

在包装非静态成员函数时会多出一个this指针参数,我们要将这一参数包含进去或者写出其函数名

function<double(Plus, double, double)> f6 = &Plus::plusd;
cout << f6(pd, 1.1, 1.1) << endl;
cout << f6(Plus(), 1.1, 1.1) << endl;
  • 1.
  • 2.
  • 3.

3、绑定(bind)

本质返回一个仿函数

用途:

(1)调整参数顺序

using placeholders::_1;
using placeholders::_2;
using placeholders::_3;

int Sub(int a, int b)
{
	return (a - b) * 10;
}

int SubX(int a, int b, int c)
{
	return (a - b - c) * 10;
}

int main()
{
	auto sub1 = bind(Sub, _1, _2);
	cout << sub1(10, 5) << endl;

	// bind 本质返回的一个仿函数对象
	// 调整参数顺序(不常用)
	// _1代表第一个实参
	// _2代表第二个实参
	// ...
	auto sub2 = bind(Sub, _2, _1);
	cout << sub2(10, 5) << endl;
  return 0;
  }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.

(2)调整参数个数

.......
// 调整参数个数 (常用)
auto sub3 = bind(Sub, 100, _1);
cout << sub3(5) << endl;

auto sub4 = bind(Sub, _1, 100);
cout << sub4(5) << endl;

// 分别绑死第123个参数
auto sub5 = bind(SubX, 100, _1, _2);
cout << sub5(5, 1) << endl;

auto sub6 = bind(SubX, _1, 100, _2);
cout << sub6(5, 1) << endl;

auto sub7 = bind(SubX, _1, _2, 100);
cout << sub7(5, 1) << endl;
.......
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

案例(存款年率)包装加绑定

// bind一般用于,绑死一些固定参数
function<double(double, double)> f7 = bind(&Plus::plusd, Plus(), _1, _2);
cout << f7(1.1, 1.1) << endl;

//auto func1 = [](double rate, double monty, int year)->double {return monty * rate * year;};
auto func1 = [](double rate, double monty, int year)->double {
	double ret = monty;
	for (int i = 0; i < year; i++)
	{
		ret += ret * rate;
	}

	return ret - monty;
	};
//以第一个为例是存三年0.015的年率
function<double(double)> func3_1_5 = bind(func1, 0.015, _1, 3);
function<double(double)> func5_1_5 = bind(func1, 0.015, _1, 5);
function<double(double)> func10_2_5 = bind(func1, 0.025, _1, 10);
function<double(double)> func20_3_5 = bind(func1, 0.035, _1, 30);

cout << func3_1_5(1000000) << endl;
cout << func5_1_5(1000000) << endl;
cout << func10_2_5(1000000) << endl;
cout << func20_3_5(1000000) << endl;
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.