I have created an example below to illustrate the problem I’m having. Basically, when I separate a template class into separate .h/.cpp file, I get unresolved symbols for the constructor. Using a single file, it compiles fine. What is causing this?
fruits.cpp:
#include "apple.h"
class FruitsDB {
public:
void addApple();
};
void FruitsDB::addApple() {
Apple<int> m;
}
int main() {
FruitsDB fruits;
return 0;
}
apple.h:
template <typename T>
class Apple {
public:
Apple();
~Apple();
};
apple.cpp
template <typename T>
Apple<T>::Apple() {
}
template <typename T>
Apple<T>::~Apple() {
}
This produces the compiler error:
g++ -c -o fruits.o fruits.cpp
g++ -c -o apple.o apple.cpp
g++ -Wall -ggdb fruits.o apple.o -o fruits
Undefined symbols:
"Apple<int>::Apple()", referenced from:
FruitsDB::addApple() in fruits.o
"Apple<int>::~Apple()", referenced from:
FruitsDB::addApple() in fruits.o
ld: symbol(s) not found
I thought it was my code causing the problem, but consolidating files doesn’t produce the problem. I’m assuming I need to include a file somewhere where I’m not. I’m totally lost.
Note: Adding template <> Apple<int>::Apple() {} in apple.cpp will resolve this, but I’m using templates to avoid having to write all those constructors, etc.
Just put your template function definitions in your header files. The thing about template functions is, they aren’t actually functions. They are templates of functions. So they can’t be compiled out of context like normal functions. They can only be compiled if the template parameters are known. So the compiling is done when the file that uses them calls the function. In order for that to happen, the template needs to be visible to the file from which it is called, which is why you put it in the header.