Search code examples
c++templatesforward-declarationexplicit-instantiation

Does template explicit instantiation work with forward-declared-types?


If I have a template class with some method defined in the .cpp file instead of the .h file, I can use explicit instantiation to get the compiler to avoid unresolved externals.

But would it work if the explicit instantiation is declared using a forward-declared type ?

template <typename T> struct Template
{
  void someFunc(); //defined in the .cpp file
}

class A;

template Template<A>;

Would it work if A is finally not defined and Template<A> not used ?


Solution

  • First of all. The compiler only generates code if the template is instantiated (in your example no code is generated because there is no instantiation). Second, you pass a type template argument. Here the compiler would be allowed to safely create an instance. In your example you do not use the type somewhere, but if you would e.g. to define a function, my first sentence would apply again, and the function is just generated upon instantiation somewhere. Just at this moment the compiler must have all the knowledge to generate the code.

    // Example program
    #include <iostream>
    
    
    template <typename T> struct Template
    {
      void someFunc(); //defined in the .cpp file
    };
    
    class A;
    Template<A> foo;
    

    However, if you create a template taking a non-type parameter. It will fail because the type definition is incomplete, as you were concerned of.

    // Example program
    #include <iostream>
    #include <string>
    
    class A;
    
    template <A parm> struct Template
    {
      void someFunc() {
            parm.foo();   
      }
    };
    
    A a;
    using foo = Template<a>;
    

    The same for this example. Here you would create an object a and of course the compiler needs to know more about the type. This is why it fails.

    // Example program
    #include <iostream>
    
    
    template <typename T> struct Template
    {
      T a;
    };
    
    class A;
    Template<A> foo;
    

    Hope this helps.