Template实例化instantiation是由泛化的template定义式产生出实际类型和函数的过程。C++template实例化是一个基础而复杂的概念。说它复杂的一个原因是,由template产生的物体entities的定义不限于源码的某一单独位置上。template所在位置、template被使用位置、以及template argument定义位置,都在构成物体意义一事上扮演各自的角色。
本文·讲述如何组织我们的程序代码才能以正确方式运用template。我们还将讲述为解决实际实例化问题,大多数流行的C++编译器所使用的方法,尽管这些方法应该是语义等价的。
1. 随需实例化on-demand instantiation
当C++编译器见到程序中使用一个template特化体specialization,便将template parameters替换为所需的argument,以创建出这个特化体。这个过程是自动完成,无需借助任何client程序码或template定义的指示。正是这种随需实例化的特性使得C++template机制有别于其它语言的类似机制。这种机制有时也称为隐式implicit或自动automatic实例化。
随需实例化意味着,当程序用到template时,编译器需要得知该template和其某些成员的完整定义(而不仅仅是template的声明)。考虑下面的例子:
template
C
template
class C{
public:
void f(); // (3) 成员声明
}; // (4) class template定义完备
void g (C
{
c.f(); //(6) 用到了class template的定义:需要C::f()的完整定义
}
在(1)处,编译器只能见到template的声明,见不到其定义(这种声明又称为前置声明,forward declaration)。和常规classes的规则一样,不需要class template的定义,我们就可以定义给类型的指针pointer或引用reference,如这里的(2)。例如函数g()的参数类型C
这里有另外一个表达式,需要class template实例化,因为此处编译器必须知道C
C
这里必须完成实例化,这么一来编译器才知道C
有时候,从程序代码本身并不能看出某个class template的成员会被取用。例如C++的重载解析机制overload resolution便需要得知各候选参数的函数额class types:
template
class C {
public:
C(int);
};
void candidate(C
void candiate(int) {} //(2)
int main()
{
candidate(42); //上面声明的两个函数都可被调用
}
编译器会将candidate(42)解析resolve为(2)的声明。然而(1)处的声明也可能被实例化,用来确定它是否也是上述调用的一个合法候选函数(本例之中实例化可能发生),因为42可隐寓通过单自变量构造函数转型为C
2.缓式实例化Lazy instantiation
3.C++实例化模型Instantiation Model
4.实现方案Implementation Schemes
5.显式实例化Explicit Instantiation
6.小结



