各位好友, 欢迎来到 模板(T)进阶___章节 !----->模板(T)~~ 泛型编程
------>Vector ~~ List --->测试 :>
//测试环节
//
#include <iostream>
#include <vector>
#include <list>
using std :: cout;
using std :: endl;
using std :: vector;
using std :: list;
//第一种写法
template<class Container>
void Print(const Container& v)
{
	typename Container :: const_iterator it = v.begin();
  
  while(it != v.end())
  {
  	cout << *it << " ";
    ++it;
  }
  cout <<endl;
}
//第二种写法 ----->推荐
template<class Container>
void Print(const Container& v)
{
	auto it = v.begin();
  
  while(it != end())
  {
  	cout << *it << " ";
    ++it;
  }
  cout << endl;
}
int main()
{
  //遍历 vector(容器)
	vector<int> v;
  
  v.push_back(12);
  v.push_back(16);
  v.push_back(17);
  
  v.push_back(21);
  v.push_back(23);
  
  for(auto e : v)
  {
  	cout << e << " ";
  }
  cout << endl;
  
  Print(v);
  
  //遍历 List(链表)
  list<int> It;
  
  It.push_back(32);
  It.push_back(36);
  It.push_back(38);
  
  It.push_back(38);
  It.push_back(40);
  
  for(auto e : It)
  {
  	cout << e << " ";
  }
  cout << endl;
  
  Print(It);
	return 0;
}为了方便好友们, 有更好的观感体验, 现附上 彩色 代码图样 :>
-------->传统遍历打印 :>

-------->优化升级打印:>

-------->错误示范 :>


------------->正确样例 :>
------->NO. 1

------->NO. 2

-------->小结 :>

(1). 加上 “typename” 之后, 明确指明 “Container :: const_iterator” 是类型, 合乎语法 !
不加 typename --->需要将 Container 进行实例化 !毕竟 编译器在进行识别 “const_iterator”时候
------------>不知道其是 自定义类型 还是内嵌类(即对象), 还有可能是静态成员变量 !
(2). 注意 :>所有容器均 适配正向迭代器(有无 const 均可), 但不一定都会适配反向迭代器
----->其中,Vector<Vector>不支持 ostream<< (流插入), 毕竟没有重载, 但可以用 迭代器遍历 ✔
一. 非类型模板参数
------------->用一个常量作为类(函数)模板的参数, 在类(函数)模板中可将该参数当作常量使用 。
------------->代码区域 : >
//定义静态栈区
#define N 10
template<class T, size_t N>
class stack
{
public:
  void func()
  {
  	N = 0; 
  }
  
private:
  T _a[N];
	int _top;
};
int main()
{
  stack<int, 10> T1; 
  
  stack<int, 100> T2; //容量为 100 
	return 0;
}--------->彩色 代码图示 :>

-------->错误示范 :>

----->注意 :>
(1). 非类型模板参数必须在编译期就能确定结果 。
(2). 浮点数, 类对象 以及字符串是不允许作为非类型模板参数 ;
二 . 模板 特化
----->模板特化 分为 函数模板特化 与类模板特化
(1). 函数模板特化
a. 必须先有一个基础的函数模板 ;
b. 关键字 template 后面添加上 一对 空的尖括号 ;
c. 函数名后面紧跟上 一对尖括号, 尖括号内 指定需要特化处理的类型 ;
d. 函数形参 :必须要同函数模板的基础参数类型完全相同 。
------>特化 代码实现 :>
//函数 模板 特化
//
template<class T>
bool Less(T left, T right)
{
	return left < right;
}
//全特化
template<>
bool Less<int*>(int* left, int* right)
{
	return *left < *right;
}
bool Less(int* left, int* right)
{
	return *left < *right;
}
//推荐写法
template<class T>
bool Less(T* left, T* right)
{
	return *left < *right;
}
//测试环节
int main()
{
  cout << "" << Less(1, 2) << endl;
  
  int a = 1,  b = 2;
  cout << "" << Less(&a, &b) << endl;
  
  double c = 1.1, d = 2.2;
  cout << "" << Less(&c, &d) << endl;
	return 0;
}为了方便好友们, 有更好的观感体验, 现附上 彩色 代码图样 :>
--------->测试 ~~ 运行结果 :>

(2). 类模板特化
a. 全特化 --->将 模板参数列表中的所有的参数进行确定化 ;
//类模板 特化
template<class T1, class T2>
class Date
{
public:
  Date() {cout << "Date<T1, T2>" << endl << endl;}  
private:
  T1 _d1;
  T2 _d2;
};
//全特化
template<>
class Date<int, double>
{
public:
	Date() {cout << "Date<int, double>" << endl << endl;}
private:
};b. 偏特化 --->任何针对模板参数进一步进行条件限制设计的特化版本 。
--------->两种表现方式 :
部分特化 :将模板参数列表中的一部分进行参数特化 : >
//部分特化
template<class T>
class Date<T, double>
{
public:
	Date() {cout << "Date<T, double>" << endl << endl;}
private:
};---------->参数进一步 限制 :>
//限制性 特化
template<class T1, class T2>
class Date<T1*, T2*>
{
public:
	Date() {cout << "Date<T1*, T2*>" << endl << endl;}
private:
};
template<class T1, class T2>
class Date<T1&, T2&>
{
public:
	Date() {cout << "Date<T1&, T2&>" << endl << endl;}
private:
};---------->类模板特化 测试环节 :>
//测试__类模板特化
//
int main()
{
  Date<int, int> d1;
  Date<int, double> d2;
  
  Date<int*, double> d3;
  Date<double, double> d4;
  
  Date<double*, double*> d5;
  Date<void*, int*> d6;
  Date<int&, double&> d7;
	return 0;
}为了方便好友们, 有更好的观感体验, 现附上 彩色 代码图样 :>
-------->NO1.

-------->NO2.

-------->NO3.

-------->NO_A.

c. 类模板 --->应用实例 :>
------>部分代码 :>
// "Priorioty.h" ---->部分代码
#include <iostream>
#include <vecor>
#include <list>
using std :: cout;
using std :: endl;
using std :: vector;
using std :: list;
using std :: Container;
template<class T>
class Less
{
	public:
  	bool operator()(const T& left, const T& right)
    {
    	return left < right;
    }
}
//全特化
template<>
class Less<Date*>
{
	bool operator()(const Date* left, const Date* right)
  {
  	return *left < *right;
  }
}
void Test_Temp()
{
  //使用了 Less<Date>模板
	priority_queue<Date, vector<Date>, Less<Date>> pq1;
  
  pq1.push(Date(2023, 6, 7));
  pq1.push(Date(2023, 6, 8));
  pq1.push(Date(2023, 6, 13));
  
  while(!pq1.empty())
  {
  	cout << pq1.top() << " ";
    pq1.pop();
  }
  cout << endl << endl;
  
  //使用了 Less<Date*>模板
  priority_queue<Date*, vector<Date*>, Less<Date*>> pq2;
  
  pq2.push(new Date(2023, 11, 10));
  pq2.push(new Date(2023, 11, 11));
  pq2.push(new Date(2023, 11, 12));
  
  while(!pq2.empty())
  {
  	cout << *pq2.top() << " ";
    pq2.pop();
  }
  cout << endl;
}
int main()
{
  Test_Temp();
	return 0;
}各位好友, 由于篇幅限制,避免重复赘余 ------>上述,仅仅展示了 部分代码 !
其他, 没有补充的代码, 是由上几期, 在 优先队列 “Priority_queue” 当中 , 已经实现过的 !
------------------------->请好友移步上几期博文, 自行查看 !✔✔
为了方便好友们, 有更好的观感体验, 现附上 彩色 代码图样 :>

三 . 模板总结
------>优点 :>
(1). 模板增强了代码的灵活性 。
(2). 模板复用了代码, 节省了资源, 更快的迭代开发,C++ 标椎模板库(STL)因此而产生 ;
------>缺点 : >
(1). 模板导致了代码膨胀问题, 也会导致编译时间变长 ;
(2). 出现模板错误, 错误信息非常凌乱, 极其不容易定位错误 ;这个时候, 可以考虑 排除法 。
各位好友, 本期内容 已完结 !
下一期, 开战 新的领域 ------>继承 ! “敬请期待 !😊😊










