目录
函数模板
类模板
模板传入自定义类型
?模板的嵌套
函数模板重载
类模板特化
函数模板
什么是模板:把类型当做未知量,可以忽略类型的影响
声明模板的语法:
template<typename? _T>//_T是类型代号,可以更改
template<typename _T>//让编译器知道要用到未知类型_T
_T Max(_T a,_T b){return a>b? a:b;}
//可以多个未知类型
template<typename _T1,typename _T2>//typename可以换成class
void print(_T1 one,_T2 two){cout<<one<<endl;cout<two<<endl;}
#include<iostream>
using namespace std;
class Type {
public:
template<typename T>
void print(T data);
template<typename _T>
void printData(_T name) { cout << name << endl; }
protected:
};
template<typename T>//类外实现必须写这条语句
void Type::print(T data)
{
cout << data << endl;
}
template<class _T,size_t size=2>//写了这个模板后,函数不能隐式调用,且size只能传常量
void printArray(_T array) { for (int i = 0; i < 2; i++) cout << array[i] << "\t"; cout << endl; }
int main() {
Type K;
K.print(3);//隐式调用
K.printData<string>("李傕");//显式调用
int array[2] = { 0,1 };
printArray<int*,2>(array);//不做缺省只能显式调用
printArray(array);//做了缺省之后可以隐式调用
return 0;
}
- 隐式调用:正常传参即可调用
- 显式调用:函数名<类型名(参数)
- 普通函数当做函数模板
- 类的成员函数是函数模板
- 缺省写法
- 存在常量类型
类模板
template<class T>
class Type{}//只要被template修饰就是一个类模板,不用未知类型也可以
- 必须采用显式调用
- 类模板不是一个实际类型,所以用到类模板的地方都要使用:类名<类型>
- 多文档编程中类模板和实现必须写在一起,不能分开写
#include<iostream>
using namespace std;
template <class _T1,class _T2>
class L {
public:
L(_T1 data1,_T2 data2):data1(data1),data2(data2){}
void print() { cout << data1 << "\t" << data2 << endl; }
protected:
_T1 data1;
_T2 data2;
};
int main() {
L<int, int>M(12, 12);
M.print();
L<string, int>J("张三", 12);
J.print();
return 0;
}
模板传入自定义类型
- 基本自定义类型
- 自定义类型也是一个模板
- 操作自定义类型,关键点在于运算符重载
#include<iostream>
using namespace std;
class L {
public:
L(string name,int age):name(name),age(age){}
friend ostream& operator<<(ostream& out, const L& M) { cout << M.name << " " << M.age << endl; return out; }
bool operator>(L& a) { return this->age > a.age; }
protected:
string name;
int age;
};
template<class _T>
void print(_T one) { cout << one<<endl; }
template<class _T>
_T Max(_T a, _T b) { return a > b ?a : b; }
template<class _T>
class Node {
public:
Node(_T data, Node<_T>* next):data(data),next(next) {}
_T getData() { return data; }
Node<_T>* getNext() { return next; }
protected:
_T data;
Node<_T>* next;
};
template<class _T>
class List {
public:
List() { headNode = nullptr; }
void InsertList(_T data) {
headNode= new Node<_T>(data,headNode);
}
void printList() {
Node<_T>* pMove;
pMove = headNode;
while (pMove != nullptr) {
cout << pMove->getData() << endl;
pMove = pMove->getNext();
}
}
protected:
Node < _T>* headNode;
};
void testList() {
List<int> list;
list.InsertList(1);
list.InsertList(2);
list.InsertList(3);
list.printList();
List<L>Q;
Q.InsertList(L("张三", 15));
Q.InsertList(L("李四", 18));
Q.InsertList(L("王五", 16));
Q.printList();
}
int main() {
L M("张三",18);
print(M);
L XL("小姐", 15);
L KF("先生", 38);
L K = Max(XL, KF);
cout << K << endl;
testList();
return 0;
}
结果如图:?
?模板的嵌套
#include<iostream>
using namespace std;
template<class _T1, class _T2>
class G {
public:
G(_T1 name,_T2 age):name(name),age(age){}
friend ostream& operator<<(ostream& out, const G& kiss)
{
cout << kiss.name << " "<<kiss.age << endl;
return out;
}
protected:
_T1 name;
_T2 age;
};
template<class _T1, class _T2 >
class K {
public:
K(_T1 one,_T2 two):one(one),two(two){}
void print() { cout << one << two << endl; }
protected:
_T1 one;
_T2 two;
};
void test() {
K<G<string, int>, G<float, float>>kiss(G<string,int>("李四",19),G<float ,float>(18,19));
kiss.print();
}
int main() {
test();
return 0;
}
函数模板重载
- 模板函数和普通函数:调用函数类型一致时,优先调用普通函数
- 两个模板同时成立,优先调用匹配度高的那个
#include<iostream>
using namespace std;
void print(string a,int b) { cout << "普通打印!" << endl; }
template<class _T1,class _T2>
void print(_T1,_T2) { cout << "模板重载!" << endl; }
template<class _T1>
void print(_T1,_T1) {
cout << "一个类型!" << endl;
}
int main() {
print((string)"张三",18);//优先调用匹配的普通函数
print<string,int>( "张三",12);//显式调用一定调用模板函数
print(12,12);//当两个模板函数都满足条件,优先调用类型相似度高的
return 0;
}
类模板特化
#include<iostream>
using namespace std;
//两个未知类型
template<class _T1,class _T2>
class kit {
public:
kit(_T1 one,_T2 two):one(one),two(two){}
void pirnt() { cout << one << " " << two << endl; }
protected:
_T1 one;
_T2 two;
};
class Data {
public:
Data(int a,int b):a(a),b(b) {}
void print() { cout << a << " " << b << endl; }
protected:
int a;
int b;
};
//局部特化,特殊化
template<class _T1>
class kit<_T1,_T1>//特化产生类,类要用:类名<类型>
{
public:
kit(_T1 one,_T1 two):one(one),two(two){}
void print() {
one.print();
two.print(); }
protected:
_T1 one;
_T1 two;
};
template<>
class kit<string ,string>{
public:
kit(string one, string two):one(one),two(two){}
void print() { cout << one << " " << two << endl; }
protected:
string one;
string two;
};
int main() {
//原生模板
kit<string, int>legend("李傕", 58);
legend.pirnt();
//局部特化模板
kit<Data, Data> lee(Data(1, 2), Data(2, 3));
lee.print();
//完全特化模板
kit<string, string>hook("张三", "李四");
hook.print();
return 0;
}
|