函数模板
实例化<>可省略
类模板
实例化时<>必须写
全特化,偏特化
2、将参数进一步限制的特化:
这个类型的特化是将参数进行了进一步的限制,我们可以将参数限制为指针类型或者引用,在这种情况下才会调用这种类型的特化
#include <iostream>
using namespace std;
template<class T1, class T2>
class Data
{
public:
Data()
{
cout << "Data<T1, T2>" << endl;
}
private:
T1 _data1;
T2 _data2;
};
//这样的把所有的模板参数都进行实例特化的就叫全特化
template<>
class Data<int, char>
{
public:
Data()
{
cout << "Data<int, char>" << endl;
}
private:
int _data1;
char _data2;
};
//这里就是一个部分特化,只将第一个参数进行实例化的情况
template<class T>
class Data<int, T>
{
public:
Data()
{
cout << "Data<int, T>" << endl;
}
};
//将两个参数类型限制为指针类型,如果两个参数都是指针类型则调用这个特化
template<class T1, class T2>
class Data<T1*, T2*>
{
public:
Data()
{
cout << "Data<T1*, T2*>" << endl;
}
};
int main()
{
Data<int, int> data1;//这里会调用部分特化
Data<int, char> data2;//这里调用全特化
Data<int*, char*> data3;//这里调用类型限制的特化
}
模板的分离编译
什么是分离编译模式?分离编译模式就是我们通常在写项目是方便项目管理时所使用的将函数和类的声明放进.h
文件中而在.cpp
文件中写类定义和类成员函数定义的模式。这种方法可行就是应为我们将声明写入.h
而在需要使用的地方引入头文件,在链接过程中编译器会根据声明找到具体实现定义的地址完成链接。
模板不支持分离编译
但是这里要说的是,无论是函数模板还是类模板在没有实例化之前都是没有具体代码的,那么也就没有具体定义的地址,我们根据声明也就无法链接到定义的地方。
// a.h
template<class T>
T Add(const T& left, const T& right);
// a.cpp
template<class T>
T Add(const T& left, const T& right)
{
return left + right;
}
// main.cpp
#include"a.h"
int main()
{
Add(1, 2);
Add(1.0, 2.0);
return 0;
}
以上这个例子中的代码时编不过的,原因就是模板不支持分离编译,无法连接。
如何解决?
解决方法也很简单,最简单的就是将定义和声明都写到头文件中可以了,这样就省去了链接这个步骤,也就不存在错误了。