模板纯粹是为了将预处理宏推广到C++而来,不同于宏使用一套“指令开头用#,指令结尾不带分号,标志符定义不使用类型”的被受争议的语法。
模板的作用在于定制函数和类,因此又称模板函数和模板类,表明模板的语法形式仿照了熟悉的函数和类的语法,只是数据类型需要用关键字"template“声明为泛化的类型。
一、函数模板
//int max(int a, int b) {
// return a>b ? a : b;
//}
//
#include <stdio.h>
template <class T>
T max(T a, T b) { //泛型T的函数
return a>b ? a : b;
}
int main(void) {
printf("%d\n", max(3, 10)); //更完整写法max<int>(3, 10);
printf("%f\n", max(16.9, 2.8)); //更完整写法max<double>(16.9, 2.8)
return 0;
}
二、类模板
#include <stdio.h>
#include <typeinfo.h>
template <class T1, class T2>
class A {
T1 i;
T2 j;
public:
A(T1 t1, T2, t2) { i=t1; j=t2; }
bool comp() { return i > j; }
void print_Type(); //函数声明
};
//类外声明成员函数
template<class T1, class T2>
void A<T1, T2>::print_Type() {
printf("i的类型:%s\n", typeid(i).name());
printf("j的类型:%s\n", typeid(j).name());
}
int main(void) {
A<int, double> a(3, 67.8);
if (a.comp()) printf("i>j \n");
else printf("i<=j \n");
a.print_Type();
return 0;
}
三、模板完全特化
模板特化技术完善了模板对于函数或类的定制功能。
#include <stdio.h>
template <class T>
class A {
T i;
public:
A(T t) { i = t; }
};
//类模板A的完全特化
template<> class A<int> {
int i;
int k; //添加新数据成员
public
A(int t) { i=t; printf("hello\n"); }
void f() {} //添加新成员函数
};
int main(void) {
A<double> dObj(2.5);
A<int> iObj(5); //打印hello
return 0;
}
四、函数模板重载
类似函数重载,函数模板的重载也提供了一个修改函数模板(类成员函数模板)的途径。
#include <stdio.h>
template <class T>
void func(T a) {
printf("使用 func(T a)模板\n");
}
//函数模板的重载
template<class T1, class T2>
int func(T1 t1, T2 t2) {
printf("func2\n");
return 1;
}
int main(void) {
func(20, 40);
func(19);
return 0;
}
五、类模板继承
实现类模板的扩充和修改
#include <stdio.h>
template<class T>
class A {
public:
void funct(T a) {
return ;
}
};
//继承类B
template<class T1, class T2>
class B: public A<T1> {
public:
void func(T1 t1, T2 t2) { return; }
};
int main(void) {
B<int, doube> b;
b.func(30, 60);
A<int> a = static_cast<A<int> >(b);
a.func(10);
return 0;
}