模板可以减少代码量,可以理解为“一个瓶子可以装多种酒”,如下图所示是一个输出的模板,可以对多种类型进行
1、非类型模板参数
非类型模板参数有两个要求:1、是常量 2、必须是整形
2、函数/类模板的特化
特化可以理解为为一般的方法增加特殊版本,这样就能让在特殊的情况也能照样使用。
template<class T1,class T2>
class Data
{
public:
Data()
{
cout << "Data" << endl;
}
private:
};
//全特化
template<>
class Data<int,double>
{
public:
Data()
{
cout << "Data<int,double>" << endl;
}
private:
};
//偏特化:特化部分参数
template<class T>
class Data<T,int>
{
public:
Data() {
cout << "Data<T,int>" << endl;
}
private:
};
template<class T>
class Data<T*, T*>
{
public:
Data() {
cout << "Data<T*, T*>" << endl;
}
private:
};
int main()
{
Data<int, int> d1;
Data<int, double> d2;
Data<double, int> d3;
Data<double, double> d4;
Data<double*, double*> d5;
return 0;
}
运行结果如下:
3、模板的分离编译
在预处理、编译、汇编、链接的过程中,声明在编译时都可以通过,但是没有地址,只有在链接时拿着修饰后的函数名去其他符号表查找。
namespace Mystack
{
template<class T, class Container>
void stack<T, Container>::push(const T& x)
{
_con.push_back(x);
}
template<class T, class Container>
void stack<T, Container>::pop()
{
_con.pop();
}
}
在此情况下有三种情况;
1、函数链接查到了
2、函数链接没查到,因为函数没有定义
3、函数链接查不到,但是函数定义了
对于情况3,原理如下:由于在**.o文件中由于模板,在该文件中由于模板不能实例化,不能生成地址,所以在符号表中查不到链接。
解决方法:显示实例化,或者在一个文件中进行声明和定义