模板实例化时只对确定需要的部分进行实例化。也就是说,编译器会延迟模板的实例化。那什么是所谓的延迟呢?
当隐式实例化类模板时,同时也实例化了该模板的每个成员声明,但没有实例化相对的定义。这也存在一些例外的情况:
- 如果类模板中包含了一个匿名的union,那么该union定义的成员同时也被实例化了
- 作为实例化类模板的结果,虚函数的定义可能被实例化了,但也可能还没有被实例化,这依赖于具体的实现。实际上,很多实现都会实例化虚函数这个定义,因为实现虚函数调用机制的内部结构要求虚函数(的定义)作为链接实体存在。
当实例化模板的时候,缺省的函数调用实参是分开考虑的。确切的说,只有这个被调用的函数(或者成员函数)确实使用了缺省实参,才会实例化该实参
template <typename T>
class Safe {
};
template <int N>
class Danger {
public:
typedef char Block[N]; // N<=0 时会出错
};
template <typename T, int N>
class Tricky {
public:
virtual ~Tricky() {
}
void no_body_here(Safe<T> = 3);
void inclass() {
Danger<N> no_boom_yet;
}
// \Tvoid error() \ Danger<0> boom; \
// void unsafe(T (*p)[N]);
T operator->();
// virtual Safe<T> suspect();
struct Nested {
Danger<N> pfew;
};
union { // 匿名union
int align;
Safe<T> anonymous;
};
};
int main()
{
Tricky<int, 0> ok;
}