Powinieneś uczulić kompilator by wygenetował w pliku implementacji odpowiedni szablon. Będzie on użyty na etapie konsolidacji. Praktykuje się także wyprowadzenie takiej dyrektywy (ostatnia linia fooclass.cpp), do oddzielnych plików.
Szablony funkcji muszą mieć swoje definicje w tych samych jednostkach translacyjnych (plik źródłowy z dołączonymi nagłówkami), w których występują ich użycia.
To nieprawda w świetle tego co pisałem wcześniej. Oto prosty przykład:
fooclass.hpp:
#pragma once
template<typename T>
class FooClass {
public:
explicit FooClass(T t);
void info() const;
private:
T data;
};
fooclass.cpp:
#include "fooclass.hpp"
#include <iostream>
template<typename T>
FooClass<T>::FooClass(T t): data{t} {}
template<typename T>
void FooClass<T>::info() const {
std::cout << "FooClass::info(), data: " << data << '\n';
}
template class FooClass<int>;
main.cpp:
#include "fooclass.hpp"
int main() {
FooClass<int> fooClass(42);
fooClass.info();
}
Oficjalne FAQ komisii ISO języka C++:
https://isocpp.org/wiki/faq/templates#templates-defn-vs-decl
.. i następne 3-4 punkty.