AlexDan
AlexDan

Reputation: 3331

template implicit instantiation and inline members

I want to know when I call a member function of template class. where does the definition get generated ? for example:

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

}

so I want to know what does the template classA<int> look like at point 1 & point 2

CASE 1 :
Time 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
    };

Time 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
   };

CASE 1 :
Time t1

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

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

Time 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

So Which one of the Two Cases is correct ?

Upvotes: 4

Views: 423

Answers (1)

Eric Niebler
Eric Niebler

Reputation: 6177

Neither case 1 nor case 2. Your question "where does the definition get generated" doesn't really make sense. Perhaps you mean, "where is the point of instantiation of class member functions". In which case, the answer is: where they are used. So the constructor gets instantiated on this line:

A<int> ob; // Time t1

.. and f() gets instantiated on this line:

ob.f();    // Time t2

It doesn't matter whether the member functions are defined within the class or not.

It's also important to note that even though the functions are not instantiated if they're not used, the compiler will still parse and do some semantic analysis on the code within the functions. Think about it: you obviously can't put gobbledygook there and expect the compiler to eat it. (Some compiler, MSVC I'm looking at you, are looser in this regard than they should be.) This preliminary analysis, even before the template parameters are known, is called phase 1. Some semantic analysis can't be done until the template parameters are known, like name-lookup in type-dependent expressions. That analysis is done in phase 2, and those errors are only caught when the functions get instantiated -- at their point of use.

What does it mean for a function to be instantiated? In practical terms, it means that the internal representation that the compiler has built as a result of parsing and preliminary semantic analysis is further analyzed by supplying the template parameters, and the result is passed to the compilers back end, which emits it as code into the object file, along with the mangled name of the function so that the linker can find it. That is where the function gets "generated".

Upvotes: 4

Related Questions