Nich aufgelöstes Symbol bei Templateklasse
-
Hallo
ich habe noch nicht viel praktische Erfahrung mit Templateklassen und habe versucht eine doppelt verkettete Liste zu schreiben. Jedoch habe ich das Problem das ich nicht aufgelöste externe Symbole bekomme sobald ich Funktionen aufrufe die nicht inline gecoded sind.main.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: __thiscall CDList<int>::CDList<int>(void)" (??0?$CDList@H@@QAE@XZ)" in Funktion "_main".
CDList.hpp
#pragma once template <typename T> class CDList { public: CDList(); };CDList.cpp
#include "CDList.hpp" template<typename T> CDList<T>::CDList() { }main.cpp
#include "CDList.hpp" int main() { CDList<int> list; return 1; }
-
templates müssen im header implementiert werden...
-
Heyho,
das Problem ist, dass Templates nicht als Symbol beim Übersetzen exportiert werden können. Der Linker findet bei Deiner 'main.cpp' die Definition von CDList nicht (den eigentlichen Programmcode). Templates müssen sofort instanziiert werden können.
Die Lösung des Problems ist, jeder Übersetzungseinheit (.cpp) das komplett ausimplementierte Template mitzugeben. Dazu ist es nötig, den Code direkt in den Header zu schreiben, oder, wie ich sie nenne, "Inline-Files" einzubinden. Die erste Lösung sieht so aus:
CDList.hpp
#pragma once template <typename T> class CDList { public: CDList() { }; };main.cpp
#include "CDList.hpp" int main() { CDList<int> list; return 1; }Und das war's! Die Datei CDList.cpp kannst Du löschen. Der Code steht direkt im Header.
Die zweite Möglichkeit ist es, Deine .cpp Datei innerhalb der Headerdatei mit der #include Direktive einzubinden. Programmtechnisch ist es prinzipiell dasselbe wie bei der ersten Lösung, allerdings finde ich die Inline-File-Variante übersichtlicher. Wichtig dabei ist nur, dass Du die .cpp auch wie eine Headerdatei behandeln musst, sonst wird sie vom Compiler als Übersetzungseinheit erkannt und das läuft dann wieder schief. Im Regelfall reicht es aus, die Dateiendung in .inl oder ähnliches umzubenennen, bzw. die Datei aus dem Compilevorgang rauszunehmen.
Die zweite Lösung würde mit Deinem Code so aussehen:
CDList.hpp
#pragma once template <typename T> class CDList { public: CDList(); }; #include "CDList.inl"CDList.inl
template<typename T> CDList<T>::CDList() { }main.cpp
#include "CDList.hpp" int main() { CDList<int> list; return 1; }Hoffe das war alles einleuchtend genug und hilft

Gruß
PuerNoctis
-
Achso ok vielen dank
