模版进阶篇章

非类型模版参数

回顾:函数模版 :不用传类型,编译器会自动推导,和普通的函数调用一样

cpp 复制代码
#include<iostream>
using namespace std;
template<typename T>// T是类型
bool Less(T a, T b)// a,b是T实例化的的对象
{
	return a < b;
}
int main()
{
    cout << Less<int>(1,2) << endl;
	cout << Less(1, 2) << endl;
	return 0;
}

类模版:通过传不同的类型,编译器会自动生成不同的类,然后进行实例化对象

cpp 复制代码
namespace bit
{
	template<typename T>// T是类型
	class array
	{
		array( int size = 1 )
		{
			_array = new T[size];
			_size = size;
		}
		bool empty()
		{
			return _size == 0;
		}
		int size()
		{
			return _size;
		}
	private:
		T* _array;
		int _size;
	};
}

注意:调用函数模版时,需要传对象(匿名实例化 或者 有名实例化)

调用类模版时,需要传类型

cpp 复制代码
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
int main()
{
//函数模版
	vector<int> s = { 1, 2, 4, 6, 7,3,1 };
	sort(s.begin(), s.end(), less<int>());//升序
	for (auto& e : s)cout << e << " ";
	cout << endl;
	sort(s.begin(), s.end(), greater<int>());//降序
	for (auto& e : s)cout << e << " ";
	cout << endl;
//类模版
	priority_queue<int, vector<int>, less<int>> k;// 传的是类型
	k.push(1);
	k.push(3);
	k.push(9);
	k.push(10);
	while (!k.empty())
	{
		cout << k.top() << " ";
		k.pop();
	}
	cout << endl;
	return 0;
}

非类型模版参数

概念:将常量作为模版参数

注意:1.只有整形家族才能支持非类型模版参数

2.参数在编译时就能确定

cpp 复制代码
#include<iostream>
#include<algorithm>
using namespace std;
namespace bit
{
	template<typename T ,size_t size = 10>
	class array//静态数组
	{
	public:
		array( )
		{
			_array = new T[size];
			_size = size;
		}
		bool empty()
		{
			return _size == 0;
		}
		int size()
		{
			return _size;
		}
	private:
		T* _array;
		int _size;
	};
}
int main()
{
	bit::array<int, 20> s;
	return 0;
}

模版参数可以支持缺省参数(类似于函数)

在priority_queue中我们以vector作为priority_queue的底层(参考我的另一篇文章:详细的讲解priority_queuede的用法与底层https://blog.csdn.net/wx20041102/article/details/138355281?spm=1001.2014.3001.5501

模版特化

通常情况下,使用模板可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得到一些错

误的结果

列如:

cpp 复制代码
#include<iostream>
#include<deque>
#include<algorithm>
#include<vector>

template<typename T>
class Less
{
public:
	bool operator() (const T& x, const T& y)
	{
		return x < y;
	}
};

template<typename T>
class Greater
{
public:
	bool operator() (const T& x, const T& y)
	{
		return y < x;
	}
};


class Date
{
public:
	Date(int year, int month, int day)
		: _year(year), _month(month), _day(day)
	{}
	bool operator<(const Date& s)
	{
		if (s._year > _year)return true;
		else if (s._year == _year)
		{
			if (s._month > _month)return true;
			else if (s._month == _month)
			{
				if (s._day > _day)return true;
			}
		}
		return false;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date* p1 = new Date(2024, 1, 1);
	Date* p2 = new Date(2024, 1, 4);
	Less<Date*> ls;
	cout << ls(p1 , p2) << endl;//这里比较的是地址大小,而我们想要比较指向的内容大小
	return 0;
}

解决方案:特化

函数模版特化

步骤如下:

1.必须要有一个基础的函数模版

2.关键字template后接一对空的<>

3.直接在()中写出要特化的类型

4.函数形参表:必须要和模版参数的基础类型完全相同

cpp 复制代码
#include<iostream>
#include<vector>
using namespace std;

template<typename T>
bool Less(T& x, T& y)
{
	return x < y;
}

template<typename T>
bool Less(int*& x, int*& y)
{
	return *x < *y;
}

template<typename T>
bool Less(string*& x, string*& y)
{
	return *x < *y;
}
int main()
{
	int* p1 = new int(1);
	int* p2 = new int(3);
	cout << Less<int*>(p1, p2) << endl;
	return 0;
}

既然参数类型已经确定,那么函数模版也可以用函数重载(这是我们经常用的)

cpp 复制代码
#include<iostream>
#include<vector>
using namespace std;

template<typename T>
bool Less(T& x, T& y)
{
	return x < y;
}


bool Less(int*& x, int*& y)
{
	return *x < *y;
}


bool Less(string*& x, string*& y)
{
	return *x < *y;
}
int main()
{
	int* p1 = new int(1);
	int* p2 = new int(3);
	cout << Less<int*>(p1, p2) << endl;
	return 0;
}

类模版特化

全特化

类型全部确定

步骤如下:

1.template 后接一对<>

2.class 类型名 + < 类型 >//注意这里要将类模版中全部的参数写出来

cpp 复制代码
#include<iostream>
#include<algorithm>
using namespace std;
template<typename T , typename K>
class date
{
public:
	date()
	{
		cout << "111111111" << endl;
	}
private:
	T _a;
	K _b;
};
template<>
class date<int,char>
{
public:
	date()
	{
		cout << "22222222222" << endl;
	}
private:
	int _a;
	char _b;
};

int main()
{
	date<int, char> s;
	date<char, char> k;
	date<int, int> q;
}
偏特化
部分特化

1.template< 需要实例化的类型 >//template<typename T>

2.class <需要实例化的类型 + 缺省类型 >// class < T , char >

cpp 复制代码
#include<iostream>
#include<algorithm>
using namespace std;
template<typename T , typename K>
class date
{
public:
	date()
	{
		cout << "111111111" << endl;
	}
private:
	T _a;
	K _b;
};
template<>
class date<int,char>
{
public:
	date()
	{
		cout << "22222222222" << endl;
	}
private:
	int _a;
	char _b;
};
template<typename T >
class date< T , char >
{
public:
	date()
	{
		cout << "3333333333" << endl;
	}
private:
	T _a;
	char _b;
};
int main()
{
	date<int, char> s;
	date<char, char> k;
	date<int, int> q;
}
限制特化

以某个性质限制,列如指针 ,引用

cpp 复制代码
#include<iostream>
#include<deque>
#include<algorithm>
#include<vector>

template<typename T>
class Less
{
public:
	bool operator() (const T& x, const T& y)
	{
		return x < y;
	}
};
template<typename T>
class Less<T*>// 限制特化 只有指针才能进入这里
{
public:
	bool operator()( T* x, T* y)
	{
		return *x < *y;
	}
};


template<typename T>
class Less<T&>// 限制特化 只有引用才能进入这里
{
public:
	bool operator()( T& x, T& y)
	{
		return x < y;
	}
};


template<typename T>
class Greater
{
public:
	bool operator() (const T& x, const T& y)
	{
		return y < x;
	}
};


class Date
{
public:
	Date(int year, int month, int day)
		: _year(year), _month(month), _day(day)
	{}
	bool operator<(const Date& s)
	{
		if (s._year > _year)return true;
		else if (s._year == _year)
		{
			if (s._month > _month)return true;
			else if (s._month == _month)
			{
				if (s._day > _day)return true;
			}
		}
		return false;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date* p1 = new Date(2024, 1, 1);
	Date* p2 = new Date(2024, 1, 4);
	Less<Date*> ls;
	cout << ls(p1 , p2) << endl;
	return 0;
}
相关推荐
HABuo32 分钟前
【linux文件系统】磁盘结构&文件系统详谈
linux·运维·服务器·c语言·c++·ubuntu·centos
我在人间贩卖青春1 小时前
C++之多重继承
c++·多重继承
颜酱1 小时前
图结构完全解析:从基础概念到遍历实现
javascript·后端·算法
m0_736919101 小时前
C++代码风格检查工具
开发语言·c++·算法
yugi9878381 小时前
基于MATLAB强化学习的单智能体与多智能体路径规划算法
算法·matlab
2501_944934732 小时前
高职大数据技术专业,CDA和Python认证优先考哪个?
大数据·开发语言·python
DuHz2 小时前
超宽带脉冲无线电(Ultra Wideband Impulse Radio, UWB)简介
论文阅读·算法·汽车·信息与通信·信号处理
Polaris北极星少女2 小时前
TRSV优化2
算法
黎雁·泠崖2 小时前
【魔法森林冒险】5/14 Allen类(三):任务进度与状态管理
java·开发语言
代码游侠3 小时前
C语言核心概念复习——网络协议与TCP/IP
linux·运维·服务器·网络·算法