第9章 实例化

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