0
点赞
收藏
分享

微信扫一扫

做一个贪吃蛇小游戏happy一下

静守幸福 2023-09-28 阅读 36

前言

一、可变参数模板

template<class ...Args>
void showList(Args... args)
{
	// ...
}

1、关于解包的两种方式 

// 方法一:递归取参
void showList()
{
	cout << endl;
}
template<class T, class ...Args>
void showList(const T& t, Args... args)
{
	cout << t << " ";
	showList(args...);
}

void test13()
{
	showList();
	showList(1);
	showList(1, 'x');
	showList(1, 1.11, 'y');
}
// 方式二:利用数组自动推导元素个数
template <class T>
void PrintArg(T t)
{
	cout << t << " ";
}
template <class ...Args>
void ShowList(Args... args)
{
    // 逗号表达式
	int arr[] = { 0, (PrintArg(args), 0)...};
	cout << endl;
}
void test13()
{
	ShowList();
	ShowList(1);
	ShowList(1, 'x');
	ShowList(1, 1.11, 'y');
}

2、emplace系类接口

void test14()
{
	list<MySpace::string> l1;
	MySpace::string str1("hello");
	// 无区别
	l1.push_back(str1);    // 深拷贝
	l1.emplace_back(str1); // 深拷贝

	cout << endl << endl;
	// 无区别
	l1.push_back(move(str1)); // 移动构造
	l1.emplace_back(move(str1)); // 移动构造

	cout << endl << endl;
	// 有区别
	l1.push_back("11111");    // 拷贝构造 + 移动构造
	l1.emplace_back("11111"); // 直接构造 
}

二、lambda

1、初始lambda

struct Goods
{
	string _name; // 名字
	double _price; // 价格
	int _evaluate; // 评价
	Goods(const char* str, double price, int evaluate)
		:_name(str)
		, _price(price)
		, _evaluate(evaluate)
	{}
};

struct CmpByPriceLess
{
	bool operator()(const Goods& x, const Goods& y)
	{
		return x._price < y._price;
	}
};

struct CmpByPriceGreater
{
	bool operator()(const Goods& x, const Goods& y)
	{
		return x._price > y._price;
	}
};

void test1()
{
	vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2,
3 }, { "菠萝", 1.5, 4 } };
	// 价格升序
	sort(v.begin(), v.end(), CmpByPriceLess());
	// 价格降序
	sort(v.begin(), v.end(), CmpByPriceGreater());

}

2、lambda的使用

void test1()
{
	vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2,
3 }, { "菠萝", 1.5, 4 } };
	// 价格升序
	//sort(v.begin(), v.end(), CmpByPriceLess());
	// 价格降序
	//sort(v.begin(), v.end(), CmpByPriceGreater());
	
	// 价格升序
	sort(v.begin(), v.end(), [](const Goods& x, const Goods& y)mutable->bool 
		{ 
			return x._price < x._price; 
		});
	// 价格降序
	sort(v.begin(), v.end(), [](const Goods& x, const Goods& y)mutable->bool 
		{ 
			return x._price > x._price; 
		});
}
void test2()
{
	int a = 3;
	int b = 5; 
	// 值捕捉
	auto add = [a, b]()mutable->int 
	{ 
		a++;
		return a + b; 
	};
	// 全部值捕捉(若无参数,括号可省略;一般情况下,返回值也可以省略)
	// 如果不期望修改值传递进来的值,mutable也可以省略;
	auto sub = [=] { return a - b; };

	cout << add() << endl;
	cout << sub() << endl;
	cout << a << endl;

}
void test3()
{
	int x = 3;
	int y = 4;
	// 若添加了mutable则圆括号不可省略
	auto f1 = [&x, y]()mutable {x = 1; y = 2; };
	f1();
	cout << x << " " << y << endl;
	// 将上文所有变量以引用的方式进行捕捉
	auto f2 = [&] {x = 10; y = 20; };
	cout << x << " " << y << endl;
}
class A
{
public:
	void func()
	{
		// 捕获当前类的this指针
		auto f1 = [this] {cout << _a << endl; };
	}
private:
	int _a = 0;
};

3、lambda的底层原理

// 是否正确?
void test3()
{
	auto f1 = [](int x, int y) {return x + y; };
	//auto f2 = [](int x, int y) {return x + y; };
	auto f2 = [](int x, int y) {return x - y; };

	f1 = f2;

}
struct Fun
{
	int operator()(int x, int y)
	{
		return x + y;
	}
};

void test4()
{
	auto f1 = [](int x, int y) { return x + y; };
	Fun f2;
	// 调用lambda函数
	f1(2, 5);
	// 调用仿函数
	f2(2, 5);

}

三、包装器

1、初始function

struct ADD
{
	int operator()(int x, int y)
	{
		return x + y;
	}
};

int add(int x, int y)
{
	return x + y;
}
void test5()
{
	// 包装器封装仿函数
	function<int(int, int)> f1 = ADD();
	// 包装器封装函数指针
	int(*pf)(int, int) = add;
	function<int(int, int)> f1 = pf;
	// 包装器封装lambda函数
	function<int(int, int)> f1 = [](int x, int y) { return x + y; };
}
class A
{
public:
	// 静态成员函数
	static int func1(int x, int y)
	{
		return x + y;
	}
	// 普通成员函数
	int func2(int x, int y)
	{
		return x + y;
	}
private:
	
};
void test6()
{
	// 封装静态成员函数(类名前可加&也可不加)
	//function<int(int, int)> f1 = A::func1;
	function<int(int, int)> f1 = &A::func1;

	// 封装普通成员函数(类型前必须加&,语法规定,且参数列表中声明类名)
	function<int(A, int, int)> f2 = &A::func2;
}

2、包装器的使用场景

struct functor
{
	int operator()(int x, int y)
	{
		return x - y;
	}
};

int mul(int x, int y)
{
	return x * y;
}

void test7()
{
	vector<function<int(int x, int y)>> vfs;
	// lambda函数
	vfs.push_back([](int x, int y)-> int {return x + y; });
	// 仿函数
	functor ft;
	vfs.push_back(ft);
	// 函数指针
	int(*ptr)(int, int) = mul;
	vfs.push_back(ptr);

}

3、bind

// 调整参数顺序
void Func1(int x, int y)
{
	cout << x << " " << y << endl;
}
void test8()
{
	// 调整参数顺序
	Func1(10, 20);
	// placeholder为命名空间,_1,_2....._n都为调整的参数顺序
	auto f1 = bind(Func1, placeholders::_2, placeholders::_1);
	// 写法二
	function<void(int, int)> f2 = bind(Func1, placeholders::_2, placeholders::_1);
	f1(10, 20);
}
// 调整参数个数
class Cal
{
public:
	Cal(double rate = 2.5)
		:_rate(rate)
	{}
	double cal(int x, int y)
	{
		return (x + y) * _rate;
	}
private:
	double _rate;
};
void test9()
{
	int x = 3;
	int y = 6;
	Cal c1;
	cout << c1.cal(x, y) << endl;
	// 调整参数个数
	auto func2 = bind(&Cal::cal, c1, placeholders::_1, placeholders::_2);
	cout << func2(x, y) << endl;
}

四、线程库

1、线程库相关接口

2、关于线程库中的一些细节问题 

// vs下查看
typedef struct
{ 
    /* thread identifier for Win32 */
    void *_Hnd; /* Win32 HANDLE */
    unsigned int _Id;
} _Thrd_imp_t;
void Func1()
{
	cout << "thread 1" << endl;
}

struct Func2
{
	void operator()()
	{
		cout << "thread 2" << endl;
	}
};


int main()
{
	// 函数指针
	thread t1(Func1);
	// 传仿函数对象
	Func2 f2;
	thread t2(f2);
	// 传lambda函数
	thread t3([] { cout << "thread 3" << endl; });

	t1.join();
	t2.join();
	t3.join();
	return 0;
}

3、线程相关接口

4、线程安全相关问题

static int sum = 0;


void transaction(int num)
{
	for (int i = 0; i < num; i++)
	{
		sum++;
	}
}


int main()
{
	// 创建线程
	//template <class Fn, class... Args>
	//explicit thread(Fn && fn, Args&&... args);
	// 参数一fn通常是一个函数指针,表示该线程调用的函数
	// 参数二是可变模板参数,会自动解析,并传给我们参数函数指针所指向的函数
	thread t1(transaction, 100000);
	thread t2(transaction, 200000);

	// 线程等待(必须进行线程等待,除非子线程执行函数中进行了detach)
	t1.join();
	t2.join();

	cout << sum << endl;
	return 0;
}

5、锁的分类

static int sum = 0;
mutex mx; // 创建锁变量

void transaction(int num)
{
	// 上锁
	mx.lock();
	for (int i = 0; i < num; i++)
	{
		sum++;
	}
	mx.unlock(); // 解锁
}

int main()
{
	thread t1(transaction, 100000);
	thread t2(transaction, 200000);

	t1.join();
	t2.join();

	cout << sum << endl;
	return 0;
}

6、lockguard

#pragma once
#include <mutex>

template<class Lock>
class Lockguard
{
public:
	Lockguard(std::Lock& mt)
		:_mt(mt)
	{
		 _mt.lock();
	}
	~Lockguard()
	{
		_mt.unlock();
	}
private:
	std::Lock& _mt;
};

static int sum = 0;
mutex mx; // 创建锁变量

void transaction(int num)
{
	// 出作用域自动销毁
	lock_guard<mutex> lg(mx);
	for (int i = 0; i < num; i++)
	{
		sum++;
	}
}

int main()
{
	thread t1(transaction, 100000);
	thread t2(transaction, 200000);

	t1.join();
	t2.join();

	cout << sum << endl;
	return 0;
}

7、条件变量

举报

相关推荐

0 条评论