4

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

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

}

所以我想知道模板类在第 1点和第 2A<int>点的样子

案例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

那么这两种情况中哪一种是正确的呢?

4

1 回答 1

4

案例 1 和案例 2 都不是。您的问题“定义在哪里生成”并没有真正的意义。也许您的意思是,“类成员函数的实例化点在哪里”。在这种情况下,答案是:它们在哪里使用。所以构造函数在这一行被实例化:

A<int> ob; // Time t1

..并f()在这一行被实例化:

ob.f();    // Time t2

成员函数是否在类中定义并不重要。

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

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

于 2012-08-25T16:27:27.783 回答