Hilfe Fehlermeldung bei Template Klassen



  • Hi!

    ich habe mir ne eigene verkettete Liste gebaut, leider bekomme ich folgende Fehlermeldungen:

    Fehler	1	error C2143: Syntaxfehler: Es fehlt ';' vor '<'	e:\dateien\visual studio 2010 projects\test\test\liste.h	7	1	Test
    Fehler	2	error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.	e:\dateien\visual studio 2010 projects\test\test\liste.h	7	1	Test
    Fehler	3	error C2238: Unerwartete(s) Token vor ';'	e:\dateien\visual studio 2010 projects\test\test\liste.h	7	1	Test
    Fehler	4	error C2143: Syntaxfehler: Es fehlt ';' vor '<'	e:\dateien\visual studio 2010 projects\test\test\liste.h	8	1	Test
    Fehler	5	error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.	e:\dateien\visual studio 2010 projects\test\test\liste.h	8	1	Test
    Fehler	6	error C2238: Unerwartete(s) Token vor ';'	e:\dateien\visual studio 2010 projects\test\test\liste.h	8	1	Test
    Fehler	7	error C2143: Syntaxfehler: Es fehlt ';' vor '<'	e:\dateien\visual studio 2010 projects\test\test\liste.h	7	1	Test
    Fehler	8	error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.	e:\dateien\visual studio 2010 projects\test\test\liste.h	7	1	Test
    Fehler	9	error C2238: Unerwartete(s) Token vor ';'	e:\dateien\visual studio 2010 projects\test\test\liste.h	7	1	Test
    Fehler	10	error C2143: Syntaxfehler: Es fehlt ';' vor '<'	e:\dateien\visual studio 2010 projects\test\test\liste.h	8	1	Test
    Fehler	11	error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.	e:\dateien\visual studio 2010 projects\test\test\liste.h	8	1	Test
    Fehler	12	error C2238: Unerwartete(s) Token vor ';'	e:\dateien\visual studio 2010 projects\test\test\liste.h	8	1	Test
    

    weiss momentan echt nicht warum er mir die meldung "fehlender typspezifizierer" bringt, in der main habe ich in spitzen klammern den typ angegeben...Ich kopier mal beide header rein, ich weiss, ich sollte nicht den ganzen code reinkopieren, aber die 2 klassen sind ziemlich klein gehalten

    anbei beide Headerdateien:

    Liste.h

    #ifndef LISTE_H
    #define LISTE_H
    #include "LE.h"
    
    template <class type>
    class Liste {
    
    	LE<type>* first;
    	LE<type>* last;
    	int size;
    
    public:
    
    	Liste() {
    		first = 0;
    		last  = 0;
    		size = 0;
    	}
    
    	~Liste() {
    		while (first != 0)
    			removeFirst();
    	}
    
    	void append(type value) {
    
    		LE<type>* newLE = new LE(value, 0);
    
    		if (first == 0) 
    			first = newLE;
    
    		else {
    			last->next = newLE;
    			newLE->prev = last;
    		}
    
    		last = newLE;
    		++size;
    	}
    
    	void removeFirst() {
    
    		if (first != 0) {
    
    			LE<type>* nextFirstLE = first->next;
    
    			// Erstes Element löschen
    			delete first;
    			--size;
    
    			first = nextFirstLE;
    
    			if(first != 0) {
    				first->prev = 0;
    			}
    
    			if (first == 0) {
    				last = 0;
    			}
    		}
    	}
    
    	int getSize() const {
    
    		return size;
    	}
    
    	type getElementAt(int index) const {
    
    		if(first != 0 && this->getSize() > index && index >= 0) {
    			LE<type>* value = first;
    			for(int i = 0; i < index; i++) {
    				value = value->next; 
    			}
    			return value->data;
    		}
    		else {
    			std::cout << "Falscher Indexzugriff der Getter Methode!\n";
    			return -1;
    		}
    	}
    
    	void setElementAt(int index, type value) {
    
    		if( first != 0 && this->getSize() > index && index >= 0) {
    			LE<type>* valuePtr = first;
    			for(int i = 0; i < index; i++) {
    				valuePtr = valuePtr->next;
    			}
    			valuePtr->data = value;
    		}
    		else {
    			std::cout << "Falscher Indexzugriff der Setter Methode!\n";
    		}
    	}
    };
    
    #endif
    

    LE.h

    #ifndef LE_H
    #define LE_H
    
    template <class type>
    
    class LE {
    
    	friend class Liste<type>;
    
    	LE* next;
    	LE* prev;
    	type data;
    
    public:
    	LE(type data, LE* next) {
    		this->data = data;
    		this->next = next;
    		prev = 0;
    	}
    };
    
    #endif
    

    main.cpp

    #include <iostream>
    #include "Liste.h"
    using namespace std;
    
    int main() {
    
    	Liste<int> test;
    
    	return 0;
    }
    


  • Hallo pawl,

    Willkommen im C++-Forum!

    In Deiner Datei Liste.h fehlt ein #include "LE.h". Der Compiler kann in Zeile 7 nix mit dem LE anfangen.

    Gruß
    Werner



  • Ja Hi!

    Danke für den Hinweis! Habe es editiert im Beitrag. Wie so oft, habe ich leider wieder eine neue Fehlermeldung 😞
    Fehler 3 und 4 macht mir irgendwie zu schaffen...

    Fehler	1	error C2059: Syntaxfehler: '<'	e:\dateien\visual studio 2010 projects\test\test\le.h	8	1	Test
    Fehler	2	error C2238: Unerwartete(s) Token vor ';'	e:\dateien\visual studio 2010 projects\test\test\le.h	8	1	Test
    Fehler	3	error C2989: "Liste": Klassen-template wurde bereits als Nichtklassen-template deklariert.	e:\dateien\visual studio 2010 projects\test\test\liste.h	121	1	Test
    Fehler	4	error C3857: "Liste": Mehrere template-Parameterlisten sind nicht zulässig.	e:\dateien\visual studio 2010 projects\test\test\liste.h	5	1	Test
    Fehler	5	error C2143: Syntaxfehler: Es fehlt ';' vor '<'	e:\dateien\visual studio 2010 projects\test\test\main.cpp	8	1	Test
    Fehler	6	error C2143: Syntaxfehler: Es fehlt ';' vor '<'	e:\dateien\visual studio 2010 projects\test\test\main.cpp	8	1	Test
    Fehler	7	error C2059: Syntaxfehler: '<'	e:\dateien\visual studio 2010 projects\test\test\le.h	8	1	Test
    Fehler	8	error C2238: Unerwartete(s) Token vor ';'	e:\dateien\visual studio 2010 projects\test\test\le.h	8	1	Test
    


  • Du solltest außerdem aufpassen, dass du dir keine zirkuläre Abhängigkeit einbaust. Die Liste benutzt die Klasse LE, diese möchte allerdings schon Liste als friend festlegen. Da die Elemente sowieso nur von Liste richtig benutzt werden können, wäre es wohl die einfachste Lösung, beide Header in dieselbe Datei zu packen und z.B. Liste ganz oben einmal leer zu deklarieren.

    So habe ich es zum Kompilieren bekommen:

    template<class type>
    class Liste;
    
    template <class type>
    class LE {
    
        friend class Liste<type>;
    
        LE* next;
        LE* prev;
        type data;
    
    public:
        LE(type data, LE* next) {
            this->data = data;
            this->next = next;
            prev = 0;
        }
    };
    
    template <class type>
    class Liste {
    
        LE<type>* first;
        LE<type>* last;
        int size;
    
    public:
    
        Liste() {
            first = 0;
            last  = 0;
            size = 0;
        }
    
        ~Liste() {
            while (first != 0)
                removeFirst();
        }
    
        void append(type value) {
    
            LE<type>* newLE = new LE(value, 0);
    
            if (first == 0)
                first = newLE;
    
            else {
                last->next = newLE;
                newLE->prev = last;
            }
    
            last = newLE;
            ++size;
        }
    
        void removeFirst() {
    
            if (first != 0) {
    
                LE<type>* nextFirstLE = first->next;
    
                // Erstes Element löschen
                delete first;
                --size;
    
                first = nextFirstLE;
    
                if(first != 0) {
                    first->prev = 0;
                }
    
                if (first == 0) {
                    last = 0;
                }
            }
        }
    
        int getSize() const {
    
            return size;
        }
    
        type getElementAt(int index) const {
    
            if(first != 0 && this->getSize() > index && index >= 0) {
                LE<type>* value = first;
                for(int i = 0; i < index; i++) {
                    value = value->next;
                }
                return value->data;
            }
            else {
                std::cout << "Falscher Indexzugriff der Getter Methode!\n";
                return -1;
            }
        }
    
        void setElementAt(int index, type value) {
    
            if( first != 0 && this->getSize() > index && index >= 0) {
                LE<type>* valuePtr = first;
                for(int i = 0; i < index; i++) {
                    valuePtr = valuePtr->next;
                }
                valuePtr->data = value;
            }
            else {
                std::cout << "Falscher Indexzugriff der Setter Methode!\n";
            }
        }
    };
    
    #include <iostream>
    using namespace std;
    
    int main() {
    
        Liste<int> test;
    
        return 0;
    }
    


  • Sind wohl alles Folgefehler des ersten Fehlers.
    In LE.h kennt der Compiler die Liste<> noch nicht. Wenn Du vor der Zeile 4 in LE.h eine sogenannte Vorwärtsdeklaration einfügst:

    template< class type>
    class Liste;
    

    sollte es klappen.

    Besser wäre es, Du hast keine gegenseitigen Abhängigkeiten zwischen den Dateien. Das erreichst Du hier z.B. dadurch, dass Du die struct LE innerhalb von Liste.h deklarierst. Noch besser, wenn dies eine private Struktur von Liste<> wird. Dann entfällt in jedem Fall das LE.h

    Gruß
    Werner



  • ok, stimmt, wusste nicht wie das genau bei header files ist. Könnte ich die LE Klasse auch als innere Klasse von Liste verwenden? Habe jetzt die LE.h in die Datei Liste.h mit Vorwärsdeklaration eingefügt...aber die Fehlermeldungen kommen wie fallende Dominosteine...

    bekommst du das auch kompiliert?

    int main() {
    
    	Liste<int> test;
    	test.append(5);
    	cout << test.getElementAt(0) << endl;
    
    	return 0;
    }
    

    Fehler 1 error C2955: "LE": Für die Verwendung der template-Klasse ist eine template-Argumentliste erforderlich. e:\dateien\visual studio 2010 projects\test\test\liste.h 63 1 Test
    Fehler 2 error C2514: 'LE': Klasse besitzt keine Konstruktoren e:\dateien\visual studio 2010 projects\test\test\liste.h 63 1 Test

    die Klasse LE hat aber einen Konstruktor...irgendwie kann ich mich mit templates nicht so anfreunden...

    EDIT: hat sich erledigt hatte noch was vergessen ... new LE<type>(value, 0)... ok danke, habt mir super geholfen



  • Wenn du mit Templates Probleme hast, dann bau dir erst eine Listenimplementation mit einem konkreten Datentypen. Wenn die dann 100%ig funktioniert kannst du sie auf eine Template Lösung umstellen. Vielleicht hilft dir dieser Ansatz etwas:

    // type ist der Typname in der späteren Template Lösung
    typedef int type;
    
    // template<typename type> 
    class Liste
    {
       ...
    public:
       void append( const type& value )
       {
          ...
       }
       type& getElementAt( unsigned int Index )
       {
          ...
       }
    };
    

    Btw:
    Indexzugriffe für verkettete Listen sind nicht schön, wenn das häufige Operationen sind ist eine verkettete Liste der falsche Containertyp.



  • DocShoe schrieb:

    Btw:
    Indexzugriffe für verkettete Listen sind nicht schön, wenn das häufige Operationen sind ist eine verkettete Liste der falsche Containertyp.

    Da kann ich nur zustimmen. Es hat quasi keinen Nutzen und ist jederzeit mit Iteratoren nachstellbar. Wenn du gar nicht erst die Möglichkeit anbietest, wird der Benutzer zumindest ins Grübeln kommen und sich entweder schlau machen oder es direkt richtig verwenden.



  • Jup danke!

    Ja, das war nur als Übung für mich gedacht... 😃


Anmelden zum Antworten