Template Templates + redefinition Fehler
-
Hallo zusammen,
dieses mal habe ich mich deutlich mehr informiert(leider nur mit begrenztem Erfolg). Wie der Titel sagt geht es um Template-Templates. Als Reference habe ich gegoogelt, "Introduction to C++ Templates" von Anthony Williams gelesen und im Standardwerk von Bjarne Stroustrup "The C++ Programming Language" gesucht. Im letzten steht es bestimmt, aber im entsprechenden Kapitel habe ich nichts dazu gefunden.
Und zwar sieht mein Quellcode wie folgt aus:
#ifndef EXAMPLE_H_ #define EXAMPLE_H_ template < typename T, template < typename T > class Storage > class example { public: example(); void insert_element(T new_element); private: Storage<T> storage_; }; #include "example.cpp" #endif /* EXAMPLE_H_ */und
#include "example.h" template < typename T, template < typename T > class Storage > example<T, Storage >::example() { // TODO Auto-generated constructor stub } template < typename T, template < typename T > class Storage > void example<T, Storage >::insert_element(T new_element) { }Die Compilermeldungen sind:
../src/example.cpp:18: error: redefinition of 'example<T, Storage>::example()'
../src/example.cpp:18: error: 'example<T, Storage>::example()' previously declared here
../src/example.cpp:33: error: redefinition of 'void example<T, Storage>::insert_element(T)'
../src/example.cpp:33: error: 'void example<T, Storage>::insert_element(T)' previously declared hereKönnt ihr mir einen Tipp geben, wie ich mit diesen umzugehen hab? Leider entdecke ich nicht, wo sie vorher deklariert wurden. In diesem Zusammenhang würde ich gerne noch eine weitere Frage stellen.
template < typename T, template < typename HIER > class Storage >Beim Suchen ist mir aufgefallen, dass wo "HIER" steht schonmal ein Bezeichner vorhanden ist, aber nicht immer. Je nach Quelle. Kennt ihr ein Dokument wo genauer steht, wann dort etwas zu stehen hat und wann nicht?
Viele Grüße
MM
-
#ifndef EXAMPLE_H_ #define EXAMPLE_H_ ... #include "example.cpp" #endif /* EXAMPLE_H_ */#include "example.h" ...
-
In Worten: du hast ein Meta-Programm gebaut, was sich unendlich mal selber einbindet.
-
Hallo camper,
vielen Dank für den Hinweis mit dem Löschen der Anweisung #include "example.cpp" klappt es nun. Was mir leider nicht klar ist, wieso es an der falschen Stelle ist.
In dem Buch von "Heiko Kalista" steht folgender Tipp:
Deklarationen und Definitionen von Template-Klassen lassen sich nicht in separaten .hpp- und .cpp-Dateien unterbringen. Ein Compilerfehler ist die Folge. Man kann sich allerdings mit dem Trick weiterhelfen, die Definitionen in eine separate Datei zu schreiben und diese per #include direkt nach der Klassendeklaration einbinden
Kannst du mir sagen wieso dieser hier nicht mehr gültig ist?
Viele Grüße
MM
-
Oh, die Antwort von Ad aCTa habe ich jetzt erst gesehen.
-
Die Antwort von Ad aCTa stimmt aber nicht (ganz).
Durch die Include-Guards "EXAMPLE_H_" wird dies unterbunden:
example.cpp -> example.h -> example.cpp -> example.h (Include-Guard wirkt!).(Nichtsdestotrotz sollten sich Dateien natürlich nicht gegenseitig einbinden.)
Die Redefinition kommt dadurch zustande, daß nun example.cpp zweimal vom Compiler abgearbeitet wird (da sie selber keine Include-Guards hat - was aber auch nicht nötig ist, s.u.).
Die Datei 'example.cpp' sollte auch nicht zum Projekt hinzugefügt werden (d.h. einzeln compiliert - da unnötig).Besser ist es, du nennst die Code-Datei "example.inl" (o.ä). (s.a. FAQ-Beitrag http://www.c-plusplus.net/forum/viewtopic-var-t-is-39467.html)
Und bindest sie nun in der Header-Datei ein:
// example.h #ifndef EXAMPLE_H_ #define EXAMPLE_H_ ... #include "example.inl" #endif// example.inl // nur Template-Definitionen (kein include mehr)Und nun brauchst du nur noch in anderen Code-Dateien die Header-Datei einbinden:
// main.cpp #include "example.h" // ...So, ich hoffe dies ist dir jetzt klarer geworden (warum, weshalb, wieso)...
P.S: evtl. könnte man meinen Beitrag zum FAQ hinzufügen -)
-
Hey Th69,
vielen Dank für die Antwort:) Hat mir weiter geholfen

viele grüße
MM