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
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:This declares but does not define the function. To define it, you must include a function body:
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:
The compiler will generate two sets of machine code based on the
Base::testtemplate, one for anintand one for achar. The limitation here is that the definition of theBase::testtemplate 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 theBase::testfunction. The compiler only operates on one translation unit at a time, so it has no idea whether or not you’ve definedBase::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.