template <class T>
template <class T, class U>
template <class T, int N>
template <class T = char>
template <int Tfunc (int)>
从编译器的角度来看,模板不同于一般的函数或类。
它们在需要时才被编译(compiled on demand),
也就是说一个模板的代码直到需要生成一个对象的时候(instantiation)才被编译。
当需要instantiation的时候,编译器根据模板为特定的调用数据类型生成一个特殊的函数。
当工程变得越来越大的时候,程序代码通常会被分割为多个源程序文件。
在这种情况下,通常接口(interface)和实现(implementation)是分开的。
用一个函数库做例子
接口通常包括所有能被调用的函数的原型定义。
它们通常被定义在以.h 为扩展名的头文件 (header file) 中;
而实现 (函数的定义)
则在独立的C++代码文件中。
模板这种类似宏(macro-like) 的功能,对多文件工程有一定的限制:
函数或类模板的实现 (定义) 必须与原型声明在同一个文件中。
也就是说我们不能再 将接口(interface)存储在单独的头文件中,
而必须将接口和实现放在使用模板的同一个文件中。
回到函数库的例子,如果我们想要建立一个函数模板的库,我们不能再使用头文件(.h) ,取而代之,我们应该生成一个模板文件(template file),将函数模板的接口和实现 都放在这个文件中 (这种文件没有惯用扩展名,除了不要使用.h扩展名或不要不加任何扩展名)。
在一个工程中多次包含同时具有声明和实现的模板文件并不会产生链接错误 (linkage errors),因为它们只有在需要时才被编译,而兼容模板的编译器应该已经考虑到这种情况,不会生成重复的代码。