std templates und iteratoren



  • Hallo!

    Hoffe das ist keine dumme Frage...

    Wollte mir ne Warpper um std::map schreiben...

    template < class K, class T>
    class KeyMap
    {
        //[...]
        private:
            std::map< K, T > mMap;
            std::map< K, T >::iterator mIter; // <-- geht nicht, wieso???
    };
    

    Wie kriege ich jetzt den Iterator???
    hatte das gleiche problem schonmal als ich eine erweiterte Klasse um std:vector geschrieben hab, aber dort habe ich einfach vermieden einen iterator zu nehmen.
    Denn auch in den Methoden kann ich keinen definieren.
    Wieso nicht bzw. was ist daran falsch, wie mache ich es richtig??



  • typename vergessen?



  • wo, wie, was?? kann jemand ein beispiel geben, habe erst seit kurzem zum ersten mal selbst templates erstellt... wo müsste ich "typename" verwenden?

    btw: wann benutzt man typename und wann class??
    sind template < typename T > und template < class T > nicht identisch? Wo liegt der Unterschied?

    ...man sieht, ich brauche input... *g*



  • ich meinte:

    typename std::map< K, T >::iterator mIter;



  • ah, ok, so gehts, thx:

    template < class K, class T>
    class KeyMap
    {
        //[...]
        private:
            std::map< K, T > mMap;
            typename std::map< K, T >::iterator mIter;
    };
    

    hat vll. jemand link wo das schlüsselwort "typename" näher erklärt wird?
    meiner meinung nach müsste auch ein std:map<K, T> den richtigen iterator liefern. Wozu den Umstand mit einem zusätzlichen Schlüsselwort??



  • Ridley schrieb:

    ah, ok, so gehts, thx:

    hat vll. jemand link wo das schlüsselwort "typename" näher erklärt wird?
    meiner meinung nach müsste auch ein std:map<K, T> den richtigen iterator liefern. Wozu den Umstand mit einem zusätzlichen Schlüsselwort??

    Damit er wahrscheinlich weiss das er das Template auflösen muss,
    um den Typen festzustellen. Oder sowas. würd mich auch mal interessieren :p

    btw. cppreference.com sagt:
    http://cppreference.com/keywords/typename.html



  • das schlüsselwort macht deinen compiler nur darauf aufmerksam, dass "iterator" ein typ ist. Da der Compiler zu dem zeitpunkt noch nicht wissen kann, dass es sich um einen typ handelt musst du ihm da auf die sprünge helfen.

    Wieso er das nicht wissen kann?

    template<class T>
    struct Foo{
        typedef T Bar;//typ
    };
    template<>
    struct Foo<int>{
        static const int Bar=0;//zahlenkonstante
    };
    


  • Kurz und knapp: Ohne typename davor nimmt der Compiler an es wäre nen Objekt, da es nen Typ ist musst du ihm das mit typename sagen.



  • Im Standard zu finden unter 14.6:

    A name used in a template declaration or definition and that is
    dependent on a template-parameter
    is assumed not to name a type
    unless the applicable name lookup finds a type name or the name is
    qualified by the keyword typename.

    Wäre das nicht was für's FAQ? (Ich hoffe, da steht's noch nicht drin :))

    Wobei mich mal interessieren würde, wann dieser Fall eintritt:
    unless the applicable name lookup finds a type name



  • danke für erklärungen und links... 🙂



  • 7H3 N4C3R schrieb:

    Wobei mich mal interessieren würde, wann dieser Fall eintritt:
    unless the applicable name lookup finds a type name

    Z.B. im Fall vom Lookup von Basisklassen in einer Basisklassenliste. Hier werden non-types ignoriert, deshalb brauchst du hier auch kein typename.
    Beispiel:

    template <class T>
    struct Foo {
        typedef T AType;
    };
    
    template <class T>
    struct Bar : Foo<T>::AType {// hier kein typename nötig
        typedef typename Foo<T>::AType Bae // hier aber schon
    
    };
    

    Foo<T>::AType ist ein abhängiger Name und muss deshalb innerhalb eines Templates mit typename qualifiziert werden. Eine Ausnahme ist die Base-Class-List, da die Lookup-Regeln hier besagen, dass non-types ignoriert werden. Hier wird also automatisch angenommen, dass Foo<T>::AType einen Typ bezeichnet. Sollte sich im Instanziierungskontext dann herausstellen, dass Foo<T>::AType kein Typ ist, dann ist dein Programm "ill-formed".


Anmelden zum Antworten