Über eine std::list vom Templatetyp iterieren



  • Ich versuche in einer Template-Klasse eine Liste von einigen anderen Instanzen der selben Klasse zu halten und dann über diese Liste zu iterieren. In Code habe ich also folgendes:

    #include <list>
    
    template <class C> class listdemo {
        public:
            void somemethod();
    
        private:
            std::list< listdemo<C>* > ourlist;
    };
    
    template <class C> void listdemo<C>::somemethod() {
        std::list< listdemo<C>* >::iterator p;
    }
    

    Nun meckert mein Compiler aber über die vorletzte Zeile:

    listtest.cc: In member function ‘void listdemo<C>::somemethod()’:
    listtest.cc:12: error: expected `;' before ‘p’
    

    Was ist denn an dieser Iteratordefinition falsch? Benutze ich keine Template-Klasse, sondern eine "normale", so funktioniert std::list<listdemo*>::iterator p; ja auch.



  • versuch mal typename einzufügen:

    #include <list>
    
    template <typename C>
    class listdemo {
        public:
            void somemethod();
    
        private:
            std::list< listdemo<typename C>* > ourlist;
    };
    
    template <typename C>
    void listdemo<typename C>::somemethod() {
        std::list< listdemo<typename C>* >::iterator p;
    }
    


  • 1310-Logik schrieb:

    versuch mal typename einzufügen:

    Guter Ansatz 😃

    typename std::list< listdemo<C>* >::iterator p;
    

    Aber besser hier 😉



  • *patsch*

    Ja richtig, so war's! Ich hab schon zu lange Abstinenz 😃



  • 1310-Logik schrieb:

    versuch mal typename einzufügen:

    Nein, funktioniert auch nicht. Mit "typename" hast du mir allerdings gerade trotzdem den entscheidenden Gedankenanstoß gegeben.

    Folgender Code funktioniert:

    template <class C> void listdemo<C>::somefunc() {
        typename std::list< listdemo<C>* >::iterator p;
    }
    

    Also ein "typename" vor den Iterator-Typ eingefügt. Ausführliche Erklärung dazu findet sich in Die C++ Programmiersprache, Bjarne Stroustrup, 4. Auflage, Kapitel C.13.5.

    Kurz gesagt: Ein C++-Compiler erkennt iterator in std::list< irgendein_Template_oder_Typ_mit_Template >::iterator nicht als Datentyp. Dies liegt an der Reihenfolge in der der Compiler arbeitet, das heißt er macht die Syntaxprüfung wohl bevor der die Templateparameter ersetzt. Man muss ihm darum in dem Fall über das Schlüsselwort "typename" zusichern, dass das was er da gerade bearbeitet ein Typ sein wird.



  • LordJaxom schrieb:

    1310-Logik schrieb:

    versuch mal typename einzufügen:

    Guter Ansatz 😃

    typename std::list< listdemo<C>* >::iterator p;
    

    Aber besser hier 😉

    Jops genau. Habe ich aber Dank 13010-Logiks Gedankenanstoß inzwischen auch gefunden gehabt.

    Danke für eure Hilfe! 🙂


Anmelden zum Antworten