【问题标题】:template implicit instantiation and inline members模板隐式实例化和内联成员
【发布时间】:2012-08-25 16:09:00
【问题描述】:

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

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

}

所以我想知道模板 classA&lt;int&gt;point 1 & point 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

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

【问题讨论】:

  • 我认为所有的魔法都发生在时间 t1。模板 A 被定义。

标签: c++ templates instantiation


【解决方案1】:

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

A<int> ob; // Time t1

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

ob.f();    // Time t2

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-31
    • 2014-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-14
    相关资源
    最近更新 更多