Templates: Ist das erlaubt?



  • in einem Buch hab ich folgenden Code gesehen:

    template<class Iterator>
    Iterator::difference_type operator-(Iterator second,
    Iterator first) {
    Iterator::difference_type count = 0; // Typ enspricht z.B. int
    /*Die Differenz wird ermittelt, indem first weitergeschaltet wird, bis der Iterator
    second erreicht ist. Voraussetzung ist also, dass first nicht nach dem Iterator
    second liegt. Anders gesagt: Der Iterator second muss ggf. für first mit dem
    Operator ++ erreichbar sein.
    */
    while(first != second
    && first != Iterator()) {
    ++first;
    ++count;
    }
    // bei Ungleichheit ist second von first aus mit ++ nicht erreichbar.
    assert(current == fromWhere.current);
    return count;
    }
    

    im obigen Template wird ja der Datentyp Iterator::difference_type verwendet - ist das überhaupt so erlaubt... woher soll den der Compiler wissen, das der Iterator einen difference_type mitbringt?



  • Also prinzipiell dürfte das erlaubt sein (besser wäre es, den Rückgabetyp als "typename Iterator::difference_type" anzugeben). Der Compiler überprüft zunächst nur, ob alles syntaktisch korrekt ist (und nimmt an, daß Iterator einen difference_type kennt). Erst wenn er eine Spzialisierung dieser Funktion anlegt, kannst du Probleme bekommen (no matching definition oder so ähnlich).



  • lol - Visual Studio 2005 will es nicht übersetzen und g++ weigert sich auch... mmh...



  • Ne Fehlermeldung wäre sinvoller =o)


  • Mod

    Vertexwahn schrieb:

    in einem Buch hab ich folgenden Code gesehen:

    template<class Iterator>
    Iterator::difference_type operator-(Iterator second,
    Iterator first) {
    Iterator::difference_type count = 0; // Typ enspricht z.B. int
    /*Die Differenz wird ermittelt, indem first weitergeschaltet wird, bis der Iterator
    second erreicht ist. Voraussetzung ist also, dass first nicht nach dem Iterator
    second liegt. Anders gesagt: Der Iterator second muss ggf. für first mit dem
    Operator ++ erreichbar sein.
    */
    while(first != second
    && first != Iterator()) {
    ++first;
    ++count;
    }
    // bei Ungleichheit ist second von first aus mit ++ nicht erreichbar.
    assert(current == fromWhere.current);
    return count;
    }
    

    im obigen Template wird ja der Datentyp Iterator::difference_type verwendet - ist das überhaupt so erlaubt...

    Es ist nicht verboten, schränkt aber möglicherweise den Templateparameter ein.

    woher soll den der Compiler wissen, das der Iterator einen difference_type mitbringt?

    Tut er nicht, im Übrigen fehlt dort auf jeden Fall ein typename. Zwecks allgemeingültigkeit verlangt der Standard, dass Iteratoren eine eigene Spezialisierung von iterator_traits mitbringen, wenn das Primärtemplate nicht genügt. An dieser Stelle kommt dann wieder diese verschachtelte Deklaration zum Tragen: Das Primärtemplate von iterator_traits verweist nähmlich auf entsprechende Member des zu beschreibenden Iterators. Hat man also diese nested member im Iterator deklariert, erübrigt sich eine Spezialisierung von iterator_traits. Und weil das so ist, wird man kaum Iteratoren begegnen, die diese Definition nicht haben. So gesehen benötigt man iterator_traits nur, wenn möglicherweise Pointer im Spiel sind, verlässt sich dann aber auf etwas, dass vom Standard nicht garantiert wird.



  • camper schrieb:

    tut er nicht, im Übrigen fehlt dort auf jeden Fall ein typename

    wo fehlt ein typename?

    Knuddlbaer schrieb:

    Ne Fehlermeldung wäre sinvoller =o)

    Warning 1 warning C4346: 'Iterator::difference_type' : dependent name is not a type c:\dokumente und einstellungen\julian\desktop\stl\stl\slist.h 96
    Error 2 error C2143: syntax error : missing ';' before '-' c:\dokumente und einstellungen\julian\desktop\stl\stl\slist.h 96
    Error 3 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int c:\dokumente und einstellungen\julian\desktop\stl\stl\slist.h 96
    Error 4 error C2888: 'Iterator::difference_type difference_type' : symbol cannot be defined within namespace 'br_stl' c:\dokumente und einstellungen\julian\desktop\stl\stl\slist.h 96
    Error 5 fatal error C1903: unable to recover from previous error(s); stopping compilation c:\dokumente und einstellungen\julian\desktop\stl\stl\slist.h 96



  • Jeweils vor Iterator::difference_type muss typename stehen, damit der Compiler weiß, dass es sich um ein typedef handelt. Der Compiler glaubt sonst, dass difference_type eine statische Variable in Iterator ist.



  • schorsch code schrieb:

    Jeweils vor Iterator::difference_type muss typename stehen, damit der Compiler weiß, dass es sich um ein typedef handelt. Der Compiler glaubt sonst, dass difference_type eine statische Variable in Iterator ist.

    ... was dann wiederum die Fehlermeldung erklärt. 😃

    Gruß,

    Simon2.



  • schorsch code schrieb:

    Jeweils vor Iterator::difference_type muss typename stehen, damit der Compiler weiß, dass es sich um ein typedef handelt. Der Compiler glaubt sonst, dass difference_type eine statische Variable in Iterator ist.

    Danke! genau das wars!


Anmelden zum Antworten