TemplateFunktion in vererbter Klasse -> error LNK2019
-
@Jockelx Alles im Header zu implementieren fällt eig. raus, weil dann der Code überhaupt keine Struktur mehr hat und es handelt sich hier um sehr viele Funktionen mit sehr viel Code.
Ich hab auch mal weitergelesen und es mit "extern template" versucht, aber bis jetzt leider noch ohne Erfolg.
-
@john-0 Du meinst, dass ich die base_class.cpp in der child_class.cpp einbinden muss?
-
@rohe sagte in TemplateFunktion in vererbter Klasse -> error LNK2019:
Alles im Header zu implementieren fällt eig. raus
Nee, das fällt nicht raus, wenn du Standard-konformen Code schreiben willst.
Alles andere ist irgendein Gefrickel von Compilerherstellern oder ggf >= C++20. Laut @john-0 funktioniert das aber nicht gut. Keine Ahnung, das weiß ich nicht.Was du machen kannst und was auch jeder versteht: Du packst die Implementierungen in eine eigene Datei (*.tpp oder *.impl) und die inkludierst du dann am Ende deiner Header-Datei. Dann ist deine Header-Datei auch aufgeräumt.
-
@rohe sagte in TemplateFunktion in vererbter Klasse -> error LNK2019:
...
Alles im Header zu implementieren fällt eig. raus, weil dann der Code überhaupt keine Struktur mehr hat und es handelt sich hier um sehr viele Funktionen mit sehr viel Code.
...Man kann in templates auch Funktionen aufrufen, die nicht-templated und damit in einer .cpp Datei implementiert sind. Ich könnte jetzt sagen, dass Code dadurch strukturierter wird, weil die Zuständigkeiten besser verteilt sind. Aber dazu kenne ich deinen Code nicht, und deswegen sage ich das auch nicht.
-
@rohe sagte in TemplateFunktion in vererbter Klasse -> error LNK2019:
@john-0 Du meinst, dass ich die base_class.cpp in der child_class.cpp einbinden muss?
Grundsätzlich definiert man ein Template in einer Inklude Datei (die Dateiendung ist hier egal), außer Template Spezialisierungen die kommen in Implemtierungsdatei (.C .cc .cpp sind übliche Dateiendungen).
Sinnvoll ist es daher bei Dir gar kein base_class.cpp zu nehmen, sondern
base_class.h#ifndef BASE_CLASS_H #define BASE_CLASS_H #include <iostream> class base_class { public: base_class() = default; ~base_class() = default; base_class(base_class&) = delete; base_class(base_class&&) = delete; virtual void virtualFunction()=0; protected: template<typename pattern> void templateFunction() { pattern a = 3; std::cout << a << std::endl; }; }; #endif
zu schreiben.
-
@Jockelx sagte in TemplateFunktion in vererbter Klasse -> error LNK2019:
Laut @john-0 funktioniert das aber nicht gut. Keine Ahnung, das weiß ich nicht.
Module funktionieren in C++20 sowohl mit clang 14, GCC 11.x wie auch GCC 12.0 nicht wirklich. Wenn man von einigen trivial Beispiel absieht gibt es früher oder später ein Compilerfehler und die Übersetzung bricht ab.
-
Ok schon mal vielen Dank euch!
Es ist wohl doch nicht so einfach, wie ich dachte. Ich werd mal überlegen, wie ich das mit einer include-Datei sauber strukturieren kann.
Muss aber leider auf morgen warten, da noch ein paar Akutfälle reingekommen sind. Berichte dann aber.
-
So jetzt hab ich doch nochmal mit "extern template" herumprobiert und eine Lösung gefunden, die für mich voll funktioniert.
main.cpp:
#include "child_class.h" int main() { child_class a; a.virtualFunction(); }
base_class.h:
#pragma once #include <iostream> class base_class { public: base_class() = default; ~base_class() = default; base_class(base_class&) = delete; base_class(base_class&&) = delete; virtual void virtualFunction()=0; protected: template<typename T> void templateFunction(bool b); };
base_class.cpp:
#include "base_class.h" template<typename T> void base_class::templateFunction(bool b) { T a = 3; std::cout << a << " and " << b << std::endl; } template void base_class::templateFunction<int>(bool b);
child_clas.h:
#include "base_class.h" class child_class : public base_class { public: child_class() = default; ~child_class() = default; child_class(child_class&) = delete; child_class(child_class&&) = delete; void virtualFunction()override; };
child_class.cpp:
#include "child_class.h" extern template void base_class::templateFunction<int>(bool b); void child_class::virtualFunction() { base_class::templateFunction<int>(true); }
CMakeList.txt:
cmake_minimum_required(VERSION 3.21) project(LearningProject) set(CMAKE_CXX_STANDARD 20) add_executable(LearningProject main.cpp base_class.cpp child_class.cpp)
Entscheidend ist die Instanzierung in der base_class.cpp.
Nachdem was ich so gelesen hab, brauch ich die "extern"-Angabe in der child_class.cpp, damit das Object nicht doppelt erstellt wird (Kompilieren und Linken tuts auch ohne).
-
@rohe sagte in TemplateFunktion in vererbter Klasse -> error LNK2019:
Nachdem was ich so gelesen hab, brauch ich die "extern"-Angabe in der child_class.cpp, damit das Object nicht doppelt erstellt wird (Kompilieren und Linken tuts auch ohne).
Wenn die Implementierung des Templates nur in
base_class.cpp
verfügbar ist, dann brauchst du die "extern" Zeile gar nicht.
Und ansonsten gehört die "extern" Zeile dahin wo das Template implementiert wird.
-
Ok, top. Danke.