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

时间:2012-08-25 16:09:00

标签: 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();    // Time t2

}

所以我想知道模板类A<int>点1 &amp; 第2点

案例1:
时间t1:

 class A<int>{
    public:
    A(){cout << "A<T>::A()" << endl;} // A() body is defined inline
    void f(); // becasue I didn't call A<int>::f yet so there is just a declaration
    };

时间t1

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

案例1:
时间t1

class A<int>{
public:
A();
void f();
};

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

时间t2

  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

那两个案例中哪一个是正确的?

1 个答案:

答案 0 :(得分:4)

案例1和案例2都没有。你的问题“定义生成在哪里”并没有多大意义。也许你的意思是,“类成员函数的实例化点在哪里”。在这种情况下,答案是:使用它们的地方。因此构造函数在此行上实例化:

A<int> ob; // Time t1

..和f()在此行上实例化:

ob.f();    // Time t2

成员函数是否在类中定义无关紧要。

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

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