Question

I have a class Base in base.h, which has a template function

class Base {
 template <typename T> void test(T a);
}

this template is supposed to read in int or double type, and I have class Derived, which is derived from class Base

I tried to call function test in class Derived, but I have the linker error.

In the end, I realised that if in base.cpp, I add

void test(int a);
void test(double a);

there will be no compiler error. This solution seems awkward, is there a better solution? Thank you

Was it helpful?

Solution

C++ templates must be defined (given a complete function body) in the same translation unit (.CPP file plus all included header files) where they are used. In your header file, all you have done is declared (given the name and signature of) the function. The result is that when you include base.h, all the compiler sees is:

class Base {
  template <typename T> void test(T a);
}

This declares but does not define the function. To define it, you must include a function body:

class Base {
  template <typename T> void test(T a)
  {
    // do something cool with a here
  }
}

The reason why this is required is that the C++ compiler generates code for templates on an "as-needed" basis. For example, if you call:

Base obj;
obj.test< int >( 1 );
obj.test< char >( 'c' );

The compiler will generate two sets of machine code based on the Base::test template, one for an int and one for a char. The limitation here is that the definition of the Base::test template must be in the same translation unit (.CPP file), or else the compiler will not know how to build the machine code for each version of the Base::test function. The compiler only operates on one translation unit at a time, so it has no idea whether or not you've defined Base::test< T > in some other CPP file. It can only work with what it has at hand.

This is quite different from the way generics work in C#, Java, and similar languages. Personally I like to think of templates as a text macro that gets expanded by the compiler as needed. That forces me to keep in mind that the complete body of the template function needs to be included in any CPP file where it is used.

OTHER TIPS

You must fully define the template function test before it can be used. The easiest way to do that is just to write your function body in the header in base.h:

class Base {
 template <typename T> void test(T a)
 {
    ... function body here
 }
}

if you declare template function in base class which means it take the template argument at compile time but if u try to access through derived class which is runtime implementation so template request at compile time which ur providing at runtime is not possible ,and main thing c++ does not support this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top