通常我们在写代码的时候,都会有一个.h头文件和一个.cpp源文件,这样的好处就是代码结构清晰,便于维护。但是用在模板里的话,在编译的时候,就会出错,一个链接错误,原因就是模板的定义没有被实例化。
那么在模板里面,是用什么方式来组织源代码的呢?模板编程有三种模型来组织源代码:
1、包含模型
2、显示实例化模型
3、分离模型
在以上几种模型中,我们建议使用包含模型来组织代码,另外两种的缺陷比较大,在下面,只说说包含模型和显示实例化模型,分离模型不做介绍。
包含模式
包含模型就是把模板的声明和定义都放到头文件里,确保所有需要的模板都已经实例化。
显示实例化模型
显示实例化模型,又称手动实例化模板,它是由关键字template和紧接其后的我们所需要实例化的实体的声明组成,而且,该声明是一个已经用实参完全替换之后的声明。
比如,已经定义的cpp文件里,我们只要对其进行显示声明,那么那个链接错误就不会再出现,代码如下:
#include "test.cpp"
template void print_typeof(double const& x);
template <typename T>
void print_typeof(T const& x) {
std::cout << typeid(x).name() << std::endl;
}
显示实例化,不适合用在大的项目中,但是它本身也有优点,实例化可以在需要的时候才进行。这样我们可以避免包含庞大头文件的开销,更可以把模板定义的源文件封装起来。
整合包含模型和显示实例化模型
为了让我们能够根据实际情况,自由地选择包含模型或显示实例化模型,我们可以把模板的定义与声明放在不同的文件中。通常的做法是使用头文件来表示这两个文件。
现在,如果我们希望使用包含模型,那么只要#include"stackdef.hpp"就可以了,反之,如果我们希望显示实例化模型,我们就应该#include“stack.hpp"”,然后再提供一个含有所需要显示实例化的cpp文件就可以了。