1.什么是实例化 就是从泛型模板替换掉模板参数生成具体类型,函数,变量的过程 2.On-Demand实例化
template<typename T> class C; // #1 declaration only
C<int>* p = 0;//如果一个类型声明了他的指针或引用不需要知道完整定义
template<typename T>
class C{
public:
void f();
};
void g(C<int>&c){
c.f();//一旦访问一个类模板的成员就会需要知道这个类是否被完整定义
}
template<typename T>
void C<T>::f(){
}
再思考如下代码 C*p = new C;//在这里需要知道C的大小,也就是需要让C实例化
3.延迟实例化
template<typename T> T f(T p) { return 2*p; }
decltype(f(2)) x = 2;//这里f(2)的类型并不需要完全实例化
template<typename T> class Q {
using Type = typename T::Type;
};
Q<int>* p = 0; //在这里也不需要Q<int>的完整实例化,同样的如果完整实例化会产生error
变量模板也有部分实例化和完整实例化的区别
template<typename T> T v = T::default_value();
decltype(v<int>) s;
4.c++实例化模型
分两阶段查找名称
1.在第一阶段,当解析模板时,非依赖型名称会并用普通查找规则和ADL规则(如果可行的话)。非受限的依赖型名称(诸如函数调用中的函数名称,它们之所以是依赖型名称,是因为它们具有依赖型实参)会使用普通查找规则,但是这一查找结果并不会作为最终结果,而是要等到第二阶段的另一个查找过程完成(也就是模板实例化的时候)。
2.在第二阶段,此时的模板实例化被称作POI(point of instantiation),依赖型受限名称会在此时被查找(对选定的实例用模板实参替换模板参数),而且还会对非受限依赖型名称进行额外的ADL查找(它们曾在第一阶段进行过普通查找)。
5.POI 1.什么是POI? 当某些结构引用了模板特化,而且需要生成相应的实例的时候,会生成替换后的代码
class MyInt {
public:
MyInt(int i);
};
MyInt operator - (MyInt const&);
bool operator > (MyInt const&, MyInt const&);
using Int = MyInt;
template<typename T>
void f(T i)
{
if(i > 0) {
g(-i);
}
}
// #1
void g(Int)
{
// #2
f<Int>(42); // point of call
// #3
}
// #4
会在#4处插入POI