Wieso brauch ich hier keine template parameter?



  • //header.hpp
    class tree{
        private:
            template<class ContainerType,class Traits>
            class treeIterator;
        //rest intressiert hierbei nich
    };
    template<class ContainerType,class Traits>
    class tree::treeIterator{
        public:
            treeIterator& operator=(treeIterator Operand);
    //treeIterator kann hier templateparameter haben, muss aber nicht-wieso?
    };
    
    //iterator.cpp
    template<class ContainerType,class Traits>
    tree::treeIterator& tree::treeIterator<ContainerType,Traits>::operator=(treeIterator Operand){}
    //der rückgabetyp darf hierbei keine parameter haben, die bereichsangabe(nennt man das so?) braucht aber unbedingt die Parameter
    

    wieso kann ich bei der deklaration des operators wählen,ob ich templateparameter benutzen will oder nicht, wieso darf ich sie im rückgabetyp der definition nicht benutzen,aber wieso muss ich sie dann in der bereichsbezeichnung dann unbedingt haben?(ok der 3. punkt is mir klar, das is das normale, aber 1 und 2...)
    gibts dafür ein grund? liegts an meinem bcb? oder haben sich die leuts vom standard gesgat:kommt,lasst die programmierer ruhig mal ne stunde rumprobieren,machts so unlogisch und uneinheitlich wie möglich 🙄



  • lol. Das kann ja kein Mensch lesen...



  • dann lass ich ma die tree templates weg,waren eh nur der vollständigkeithalber dabei



  • hat keiner ne Ahnung?



  • naja, egal, es funktioniert bei mir,und damit hat sich für mich die sache, das wieso wird sich bestimmt später noch ergeben 🙄



  • otze schrieb:

    [...]
    template<class ContainerType,class Traits>
    class tree::treeIterator{
        public:
            treeIterator& operator=(treeIterator Operand);
    //treeIterator kann hier templateparameter haben, muss aber nicht-wieso?
    };
    

    Innerhalb der Klassendefinition einer Templateklasse ist der Name der Templateklasse (template name) äquivalent zur Template-Id (Name + Liste von Templateargumenten). treeIterator ist innerhalb der Klassendefinition also äquivalent zu treeIterator<ContainerType, Traits>.
    Diese "Injezierung" des Namens einer Klasse in ihren Scope gibt es genauso bei normalen Klassen. Das ganze wird bei Templates aber natürlich etwas komplizierter.

    otze schrieb:

    //iterator.cpp
    template<class ContainerType,class Traits>
    tree::treeIterator& tree::treeIterator<ContainerType,Traits>::operator=(treeIterator Operand){}
    //der rückgabetyp darf hierbei keine parameter haben, die bereichsangabe(nennt man das so?) braucht aber unbedingt die Parameter
    

    Das ist kein gültiges C++.
    Der Rückgabetyp gehört hier nicht zum Scope der Templateklasse. Das muss also korrekterweise schon mal so aussehen:

    template<class ContainerType,class Traits>
    tree::treeIterator<ContainerType, Traits>& ...
    

    Alles *nach* dem Scope-Operator (also nach tree::treeIterator<ContainerType,Traits>::) bezieht sich wiederum auf den Scope von treeIterator. Hier ist der Name der Klasse wieder äquivalent zur Template-Id und damit treeIterator äquivalent zu treeIterator<ContainerType, Traits>.
    Das selbe Phänomen kennst du auch von normalen Klassen:

    class Bar {};
    class Foo
    {
    public:
        class Bar {};
        Bar func(Bar b);   // Foo::Bar
    };
    
    Foo::Bar   // außerhalb von Foo, also qualifiziren
    Foo::
    func(Bar b)// jetzt sind wir innerhalb von Foo
    {
        Bar b2; // Foo::Bar
        return b;
    }
    

    wieso kann ich bei der deklaration des operators wählen,ob ich templateparameter benutzen will oder nicht, wieso darf ich sie im rückgabetyp der definition nicht benutzen

    Du darfst sie nicht nur benutzen, du *musst* sogar. Wenn dein Compiler das auch ohne erlaubt, ist das ein Fehler deines Compilers.

    ,aber wieso muss ich sie dann in der bereichsbezeichnung dann unbedingt haben?

    Weil du sonst z.B. nicht zwischen einem Basetemplate und einer partiellen Spezialisierung unterscheiden könntest. Du musst bei der Definition einer Methode eines Templates außerhalb der Klassendefinition deshalb immer die vollständige Template-Id angeben zu der die Definition gehören soll.

    standard gesgat:kommt,lasst die programmierer ruhig mal ne stunde rumprobieren,machts so unlogisch und uneinheitlich wie möglich 🙄

    Bitte schieb dein Unverständnis jetzt nicht anderen in die Schuhe. Die Regeln sind zwar komplex, dennoch aber logisch und in sich geschlossen.
    Wenn du keine Lust hast die Regeln zu lernen, kannst du ja einfach immer alles vollqualifizieren:

    class tree{
        private:
            template<class ContainerType,class Traits>
            class treeIterator;
    };
    template<class ContainerType,class Traits>
    class tree::treeIterator{
        public:
            treeIterator<ContainerType, Traits>& operator=(treeIterator<ContainerType, Traits> Operand);
    }; 
    
    template<class ContainerType,class Traits>
    tree::treeIterator<ContainerType, Traits>& tree::treeIterator<ContainerType,Traits>::operator=(tree::treeIterator<ContainerType,Traits> Operand){return *this;}
    

    Das ist nicht falsch, nur etwas gesprächig.



  • HumeSikkins schrieb:

    otze schrieb:

    [...]
    template<class ContainerType,class Traits>
    class tree::treeIterator{
        public:
            treeIterator& operator=(treeIterator Operand);
    //treeIterator kann hier templateparameter haben, muss aber nicht-wieso?
    };
    

    Innerhalb der Klassendefinition einer Templateklasse ist der Name der Templateklasse (template name) äquivalent zur Template-Id (Name + Liste von Templateargumenten). treeIterator ist innerhalb der Klassendefinition also äquivalent zu treeIterator<ContainerType, Traits>.
    Diese "Injezierung" des Namens einer Klasse in ihren Scope gibt es genauso bei normalen Klassen. Das ganze wird bei Templates aber natürlich etwas komplizierter.

    ok, das wusste ich nicht

    otze schrieb:

    //iterator.cpp
    template<class ContainerType,class Traits>
    tree::treeIterator& tree::treeIterator<ContainerType,Traits>::operator=(treeIterator Operand){}
    //der rückgabetyp darf hierbei keine parameter haben, die bereichsangabe(nennt man das so?) braucht aber unbedingt die Parameter
    

    Das ist kein gültiges C++.
    Der Rückgabetyp gehört hier nicht zum Scope der Templateklasse.

    der bcb 6.0 erlaubt es mir aber nicht so,wie es richtig wäre,deshalb wundere ich mich ja

    template<class ContainerType,class Traits>
    tree::treeIterator<ContainerType, Traits>& ...
    

    Alles *nach* dem Scope-Operator (also nach tree::treeIterator<ContainerType,Traits>::) bezieht sich wiederum auf den Scope von treeIterator. Hier ist der Name der Klasse wieder äquivalent zur Template-Id und damit treeIterator äquivalent zu treeIterator<ContainerType, Traits>.

    das wusste ich 😉

    wieso kann ich bei der deklaration des operators wählen,ob ich templateparameter benutzen will oder nicht, wieso darf ich sie im rückgabetyp der definition nicht benutzen

    Du darfst sie nicht nur benutzen, du *musst* sogar. Wenn dein Compiler das auch ohne erlaubt, ist das ein Fehler deines Compilers.

    cool, der bcb 6.0 hat fehler 🙄

    standard gesgat:kommt,lasst die programmierer ruhig mal ne stunde rumprobieren,machts so unlogisch und uneinheitlich wie möglich

    Bitte schieb dein Unverständnis jetzt nicht anderen in die Schuhe. Die Regeln sind zwar komplex, dennoch aber logisch und in sich geschlossen.

    die regeln kenn ich ja, und die sind auch logisch, ich habs auchs chon 100 mal vorher gemacht, nur nie mit nested klassen, und da wars halt unlogisch(aber auf dem compiler basierend)

    darf ich die schuld denn nun auf den compiler schieben? 🙄


Anmelden zum Antworten