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)
-
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!