C++ 模板隐式实例化和内联成员

C++ 模板隐式实例化和内联成员,c++,templates,instantiation,C++,Templates,Instantiation,我想知道何时调用模板类的成员函数。定义是在哪里生成的?例如: template <class T> class A{ public: A(){cout << "A<T>::A() " << endl;} void f(){cout << "A<T>::f() " << endl;} }; int main(){ A<int> ob; // Time t1 ob.f();

我想知道何时调用模板类的成员函数。定义是在哪里生成的?例如:

template <class T>
class A{
     public:
     A(){cout << "A<T>::A() " << endl;}
     void f(){cout << "A<T>::f() " << endl;}
};

int main(){
A<int> ob; // Time t1
ob.f();    // Time t2

}
模板
甲级{
公众:

A(){cout案例1和案例2都没有。你的问题“定义在哪里生成”没有真正意义。也许你的意思是,“类成员函数的实例化点在哪里”。在这种情况下,答案是:它们在哪里使用。因此构造函数在这一行实例化:

A<int> ob; // Time t1
ob.f();    // Time t2
成员函数是否在类中定义并不重要

同样重要的是要注意,即使函数没有被实例化,如果它们没有被使用,编译器仍然会对函数中的代码进行解析和语义分析。想想看:显然,你不能把gobbledygook放在那里,而期望编译器吃掉它。(一些编译器,我在看你们的MSVC,在这方面比他们应该做的更松散。)即使在模板参数已知之前,这种初步分析也被称为第1阶段。在模板参数已知之前,某些语义分析无法完成,比如类型相关表达式中的名称查找。这种分析在第2阶段完成,只有在函数在其使用点被实例化时,才会发现这些错误


实例化函数意味着什么?实际上,这意味着编译器通过解析和初步语义分析构建的内部表示将通过提供模板参数进行进一步分析,并将结果传递给编译器后端,后者将其作为代码发送到object文件,以及函数的损坏名称,以便链接器可以找到它。这就是函数“生成”的地方。

我认为所有的神奇都发生在时间t1。模板A得到定义。
class A<int>{
public:
A();
void f();
};

A<int>::A(){cout << "A<T>::A()" << endl;} // this is not inline
  class A<int>{
    public:
    A();
    void f();
    };

A<int>::A(){cout << "A<T>::A()" << endl;} // this is not inline
void A<int>::f(){cout << "A<T>::f() " << endl;}// this is not inline
A<int> ob; // Time t1
ob.f();    // Time t2