Templates mit Iteratoren
-
Hi,
Hab eine simples Problem hoffe ich.
Habe eine Tools.cpp angelegt, in der paar Funktionen drin sind.
Eine davon soll eine werden, die einen Iterator über eine Liste cyklisch navigiert.
Der Kopf sieht so aus:
void CycleIncrementIterator(std::list<KLASSENNAME*>::iterator &it,std::list<KLASSENNAME*> &Polygons)Geht auch einwandfrei!!!
Wenn ich das aber mit einem Template vereinfachen will zu:
template <class T> void CycleIncrementIterator2(std::list<T&>::iterator &it,std::list<T&> &Polygons)kommt die Fehlermeldung:
error C2065: 'it': nichtdeklarierter Bezeichner error C2065: 'Polygons': nichtdeklarierter Bezeichner error C2275: 'std::list<T&>': Ungültige Verwendung dieses Typs als Ausdruck error C2182: 'CycleIncrementIterator2': Unzulässige Verwendung des Typs 'void' error C2998: 'int CycleIncrementIterator2': Kann keine Vorlagendefinition seinWo kann denn da mein Denkfehler sein?
Vielen Dank für alle Tipps
-
KLASSENNAME*
und
T&finde den Fehler.
PS:
ich würde einen cycle iterator definieren der auf allen containern arbeiten kann. er muss ja nur end() kennen und kann als iterator adapter fungieren...
-
Ok, die void klasse ist leer, für den testzweck.
Sowohl
template <class T> void CycleIncrementIterator2(std::list<T*>::iterator &it,std::list<T*> &Polygons)als auch
template <class T> void CycleIncrementIterator2(std::list<T>::iterator &it,std::list<T> &Polygons)Führen zum gleichen Fehler!
Noch mal der Inhalt der Funktion ist
{ }Oder hab ich den Tipp nicht verstanden?
Tante Edit hat gerade nochmal dein PS gelesen und meint, dass dass definitiv das geilste wäre. Leider hab ich keine Idee, wie das gehen soll. Hab vorher noch nicht mit templates gearbeitet, will aber ja jetzt mal was lernen

-
Ein Standardproblem: Da T zum Zeitpunkt der Deklaration noch nicht bekannt ist, ist auch list<T> nicht bekannt (auch wenn das Template list<> bereits bekannt ist - Stichwort Spezialisierung). Daher weiss der Compiler nicht, dass list<T>::iterator ein Typ ist (oder sein wird).
Um dem Compiler dies mitzuteilen, verwende
typename std::list<T>::iterator.
-
So sieht das gut aus.
Hab jetzt in der Header Datei die Datei formuliert, inclusive realisierung.
Eine Variante so
template <class T> void CycleDecrementIterator(typename std::list<T>::iterator &it,std::list<T> &Polygons)eine so
template <class T> void CycleDecrementIterator(typename std::list<T*>::iterator &it,std::list<T*> &Polygons)Daduch geht das 1a sowohl auf listen auf zeigen als auch auf listen von "nichtzeigern"^^
Zwei fragen hab ich noch.
1. Wie kriege ich die Definition der Funktion in die Cpp Datei?
--> Muss ich über beides dieses Template schreiben? Dann springt mir der Linker an den hals.
2. Kann man obige Versionen Zusammenfassen?
Vielen Dank, es geht ja erstmal

-
curator schrieb:
Daduch geht das 1a sowohl auf listen auf zeigen als auch auf listen von "nichtzeigern"^^
Dafür würde aber die erste Version reichen. Du kannst als Typ schliesslich auch ein
double*übergeben.curator schrieb:
1. Wie kriege ich die Definition der Funktion in die Cpp Datei?
--> Muss ich über beides dieses Template schreiben? Dann springt mir der Linker an den hals.
Gar nicht. Templates müssen in der Headerdatei definiert werden (sofern du nicht das Schlüsselwort
exportnutzt, das fast kein Compiler unterstützt). Du kannst aber zur besseren Trennung eine .impl, .inl oder .ipp-Datei mit den Definitionen machen und diese Datei am Schluss des Headers einbinden.curator schrieb:
2. Kann man obige Versionen Zusammenfassen?
Ja, wie gesagt.
-
Nexus schrieb:
Gar nicht. Templates müssen in der Headerdatei definiert werden (sofern du nicht das Schlüsselwort
exportnutzt, das fast kein Compiler unterstützt). Du kannst aber zur besseren Trennung eine .impl, .inl oder .ipp-Datei mit den Definitionen machen und diese Datei am Schluss des Headers einbinden.Was natürlich für template-Spezialisierungen nicht gilt. Die kann man auch in eine .cpp packen.