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 
    sein
    

    Wo 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 export nutzt, 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 export nutzt, 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.


Anmelden zum Antworten