定义:对于函数模板和类模板,模板参数并不局限于类型,普通值也可以作为模板参数
非类型模板参数定义的是常量
template
class array;
//T:类型模板参数
//N:非类型模板参数,一个常量
使用场景:
template
class Stack{
private:
T _arr[N];
int _top;
};
int main(){
Stack st1;
Stack st2;
return 0;
}
注意:
template
class Stack{
public:
void f(){
N=10; //不可修改非类型模板参数
}
private:
T _arr[N];
int _top;
};
int main(){
Stack st1;
st1.f();
return 0;
}
#include
#include
#include
using namespace std;
int main() {
vector v1(100, 0);
array a1;
cout << "size of v1:" << sizeof(v1) << endl;
cout << "size of a1:" << sizeof(a1) << endl;
return 0;
}
vector 在堆上开辟空间,array 在栈上开辟空间
用 array 对标 vector 是错误的,与原生数组可以对比
array a1;
int a2[100];
array 的最大优势:有一个越界的检查,读和写都可以检查到是否越界
总结:array 相较于原生数组,有越界检查的优势,实际中建议直接使用 vector
引入:给特殊类型准备特殊模板。使用模板可以实现一些与类型无关的代码,对于一些特殊类型,对其进行一些“特殊的处理”
定义:针对某些类型进行特殊化处理
步骤:
PS:函数模板不一定非要特化,写一个匹配参数的普通函数更容易理解
#include
#include "Date.h"
using namespace std;
//函数模板
template
bool Less(T left, T right){
return left < right;
}
//函数模板的特化处理
template<>
bool Less(Date* left, Date* right){
return *left < *right;
}
//直接匹配的普通函数
bool Less(Date* left, Date* right){
return *left < right;
}
int main(){
cout << Less(1, 2) << endl;
Date d1(2022, 7, 7);
Date d2(2022, 7, 8);
cout << Less(d1, d2) << endl;
Date* p1 = new Date(2022, 7, 16);
Date* p2 = new Date(2022, 7, 15);
cout << Less(p1, p2) << endl;//若存在直接匹配的普通函数(函数重载),会优先使用现成的函数重载,不用实例化
return 0;
}
类模板无法实现一个具体的实际类型,故必须特化
#include
using namespace std;
template
//类模板
class Data {
public:
Data() {
cout << "Data " << endl;
}
private:
T1 _d1;
T2 _d2;
};
//类模板的特化
template<>
class Data {
public:
Data() {
cout << "Data " << endl;
}
};
int main(void) {
Data d1;
Data d2;
return 0;
}
定义:将模板参数列表中所有的参数都确定化
#include
using namespace std;
//类模板
template
class Data {
public:
Data() {
cout << "Data " << endl;
}
private:
T1 _d1;
T2 _d2;
};
//全特化
template<>
class Data {
public:
Data() {
cout << "Data " << endl;
}
};
int main(void) {
Data d1;
Data d2;
return 0;
}
定义:将部分参数类表中的一部分参数特化
#include
using namespace std;
//类模板
template
class Data {
public:
Data() {
cout << "Data " << endl;
}
private:
T1 _d1;
T2 _d2;
};
//半特化
template
class Data {
public:
Data() {
cout << "Data " << endl;
}
};
//半特化的另一种表现形式,可以对参数进行进一步限制
//限制两个参数都是指针:只要两个参数都是指针,就匹配
template
class Data {
public:
Data() {
cout << "Data " << endl;
}
};
//限制两个参数都是引用:只要两个参数都是引用,就匹配
template
class Data {
public:
Data() {
cout << "Data " << endl;
}
};
int main(void) {
Data d3; // Data
Data d4; // Data
Data d5; // Data
Data d6; // Data
Data d7; // Data
Data d8; // Data
Data d9; // Data
Data d10; // Data
Data d11; // 编译错误
return 0;
}