19.模版进阶(上)

algorithm算法里有堆排序

默认sort是快排,

了解下:

报错。得是堆才能排

这个判断是不是堆。

也有建堆算法

优先级队列不想自己写,是可以调用这块的算法。这也是走一个向上调整算法

这个本质也是个向下调整算法。优先级队列是将这个堆算法结合起来形成一个适配器。

看一个奇怪的东西:

所说的不仅仅是这一个算法,要求穿一个迭代器,可以穿vector迭代器,也可以传数组的指针,物理空间连续情况下,原生指针就是天然的迭代器,sort也可以排序数组。vector string,可以用原生指针替代iterator,看起来是iterator实际就是原生指针,前提是底层是个连续的物理空间,

看一下仿函数,实践当中不需要写less和greater,直接用就行。

在function的一个头文件,有时候也不需要包,被间接包了,

仿函数一般不需要我们自己写,但是有一些场景必须自己写

cpp 复制代码
class Date
{
	friend ostream& operator<<(ostream& _cout, const Date& d);
public:
	Date(int year = 1900, int month = 1, int day = 1)
		: _year(year)
		, _month(month)
		, _day(day)
	{}

	bool operator<(const Date& d)const
	{
		return (_year < d._year) ||
			(_year == d._year && _month < d._month) ||
			(_year == d._year && _month == d._month && _day < d._day);
	}

	bool operator>(const Date& d)const
	{
		return (_year > d._year) ||
			(_year == d._year && _month > d._month) ||
			(_year == d._year && _month == d._month && _day > d._day);
	}
private:
	int _year;
	int _month;
	int _day;
};

我们直接用日期类对象做这个,插入日期类支持,因为priority queue默认仿函数是less,less内调用的是比较大于和小于,日期类对象支持大于和小于,也就是说,类类型也没关系,自己支持一下就OK。

这种可以控制住,

第一次是30 28 29

每次生成都不一样,底层依靠指针,也就是地址比,而且地址是随机的,先new不一定大,

缺省值不传按date*比,传了按指向去比。,降序operator反过来就行

模版进阶

之前叫类型模版参数

现在学

我们定义一个静态的栈,可以不要参数,直接用常量,定义的是常量,可以直接用来做数组的大小,编译时候就确定了,模版在编译时候就实例化了,比起宏的好处是什么,宏是写死的

非类型模版参数就可以帮忙解决这个问题,本质底层生成两个类,一个类N是5,一个N是10,,非类型模版定义的常量。

非类型模版参数只能用于整形,其他类型不可以,C++20才能用double

非类型模版参数主要就是为了定义一些大小,固定值,这种。解决这个问题。非类型模版参数可以给缺省值。

推荐这样写。都支持,向前兼容。可以写两个模版参数

布尔也算整形,整形家族,char int lnog 有符号 无符号 布尔

array是个静态数组, 迭代器是随机迭代器,原生指针实现的,用非类型模版参数。(非常适合)

也没初始化

底层类似这个

越界检查问题用这个很爽,越界读基本上检查不出来,越界写标志位能被检查。数组检查是设标志位的检查,就是抽查,数组后面给两个标志位,一个或者三个,给-1,看有没有被修改,没修改就检查不出来,这就是抽查机制,如果往后面,就检查不出来。因为这不是标志位。所以越界检查,C语言的普通静态数组是抽查,越界读不检查,写是抽查,多设置标志位,检查不完,

array越界读写都能检查。不是设标志位了,他是自定义类型,要调用operator【】,operator【】就可以强制加个断言检查,

vector不仅可以越界检查,还可以初始化,为什么用静态数组,还是有本质区别,vector在堆,array在栈,栈上开空间比堆上效率高。vector不管多大数组,始终16字节,arrray大小数组越大,占用越大。ayyar对比静态数组越界检查会更好,对比vector数据空间在栈上,效率高,一句指令就把所有变量空间开好了

模板的特化

函数模版可以特化,但是很多坑

指针比交,控制不住,所以函数模版特化,

特化是说当这个T类型是其他类型走上面,DAte*走下面这个,对DAte*特殊处理,

特化很不好,可以不用特化,直接写个函数

末班和现成的用现成的。所以函数模版推荐这样写。这个和特化可以同时存在,调用固定函数,特化不起作用了。

为什么函数模版特化恶心:

内置类型还好,自定义类型要调用拷贝构造。不好要这么写

这样写,特化不行,没跟原来地方完整匹配。

那我也这样写

也不行,因为上面const修饰left,修饰引用本身,下面const修饰指向内容,所以要把const放到*之后

还是直接用函数好

能不能匹配上特化上面那个可以匹配上,下一个匹配不上,匹配到原模版去了,特化的DAte*,和const DAte* 是两个类型,constDAte* 不能给DAte*,因为权限呗放大了,

这样就可以了。cosnt DAte*是本来就要特化成的。第二个const要修饰引用对象本身,对于普通类型const既可以放到之前也可以放到之后

这样写也可以

引用也可以

没有指针可以随便颠倒。

第一个匹配不上了

第二个可以走特化

特化两个版本可以解决这个问题

所以用普通函数很好,不写特化,DAte*权限缩小都不行,这里模版还是蛮严谨的。

这里也要写两份才能都匹配,特化是真的不好玩。特化必须和原模板相匹配。

相关推荐
yuuki23323327 分钟前
【C++】初识C++基础
c语言·c++·后端
小年糕是糕手27 分钟前
【C++】类和对象(二) -- 构造函数、析构函数
java·c语言·开发语言·数据结构·c++·算法·leetcode
玫瑰花店1 小时前
SomeIP报文详解
c++·someip
利刃大大1 小时前
【c++中间件】redis介绍 && redis-plus-plus库使用
c++·redis·中间件
永不停转1 小时前
关于 QGraphicsItemGroup 内部项目发生变化后group重新定位的问题
c++·qt
IT永勇2 小时前
C++设计模式-装饰器模式
c++·设计模式·装饰器模式
Murphy_lx2 小时前
std_ofstream
c++
草莓熊Lotso2 小时前
红黑树从入门到进阶:4 条规则如何筑牢 O (logN) 效率根基?
服务器·开发语言·c++·人工智能·经验分享·笔记·后端
啊董dong2 小时前
课后作业-2025年11月23号作业
数据结构·c++·算法·深度优先·noi