PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Iteratoren bei VS2005 und VS2008 Beta2


Asmodeus
2007-09-25, 20:12:21
Ich habe folgende Unterschiede bei der Verwendung von Iteratoren bemerkt:


1. list<int> IntList;
2. list<int>::iterator IntListIterator;
3. IntListIterator = NULL;


Unter VS2005 wird dieses Codesegment ohne Meldungen vom Kompiler akzeptiert. Unter VS2008 Beta2 bekomme ich für die 3. Zeile die Fehlermeldung, dass ein int Wert (NULL) nicht in den Iteratortyp konvertiert werden kann. Beruht dieser Fehler auf dem Betastatus von VS2008, oder wurde bei VS2008 grundlegend etwas an den Iteratoren geändert? Ich habe z.B. festgestellt das bei der Beta2 von VS2008 folgende neue Membervariable bei den Iteratoren dazu gekommen ist:


IntListIterator._Ptr


Müsste ich bei VS2008 dann also diesen Pointer gleich NULL setzen, oder hat es damit eine andere Bewandnis?

Gruß, Carsten.

Trap
2007-09-25, 20:23:23
Was ist bei dir NULL?

Ein iterator hat laut Standard kein =, das auf der rechten Seite etwas anderes als einen Iterator des gleichen Typs akzeptiert.

Asmodeus
2007-09-25, 22:07:04
Was ist bei dir NULL?

Na wie immer: #define NULL 0


Ein iterator hat laut Standard kein =, das auf der rechten Seite etwas anderes als einen Iterator des gleichen Typs akzeptiert.

Da es bei VS2005 trotzdem funktioniert ist also davon auszugehen, dass es "unsauber" in VS2005 spezifiziert ist und bei VS2008 jetzt korrekt implementiert wurde und deswegen dort jetzt auch die entsprechende Fehlermeldung kommt?

Gruß, Carsten.

Trap
2007-09-25, 23:02:26
Auf jeden Fall ist die Fehlermeldung bei VS2008 kein Bug, wenn von dem zusätzlichen operator=/Konstruktor in der Doku zu VS2005 nichts steht, dann funktioniert es einfach "durch Zufall".

Coda
2007-09-26, 02:31:41
"NULL" ist bei Iteratoren eigentlich .end() des jeweiligen Containers.

Übrigens sollte man eh 0 statt "NULL" bei C++ verwenden. Macros sind böse.

Asmodeus
2007-09-26, 07:51:26
"NULL" ist bei Iteratoren eigentlich .end() des jeweiligen Containers.
...


Nur diese Einschränkung verstehe ich nicht ganz. Syntaktisch ist es nicht erforderlich, dass ein Iterator immer im Zusammenhang mit einem Container steht. Wenn man die Initialisierung des Iterators mit "NULL" nun aber nur dadurch erreicht, in dem man den Iterator auf .end() eines entsprechenden Containers setzt, so ist das meiner Meinung nach eine Einschränkung, die falsch ist. Es muss doch auch so möglich sein, für einen Iterator abzufragen, ob er überhaupt schon an einen Container gebunden ist, oder noch frei ist. Bei der Beta von VS2008 gibt es dafür ja jetzt beispielsweise die Iteratorfunktion _Has_container() die einem dann true oder false zurückliefert. Nur wie kann man unter VS2005 diesen Zustand des Iterators abfragen, wenn man nicht dieses Konstrukt Iterator = 0 benutzt, um dann später abfragen zu können if(Iterator == 0).

Gruß, Carsten.

micki
2007-09-26, 08:36:59
Nur diese Einschränkung verstehe ich nicht ganz. Syntaktisch ist es nicht erforderlich, dass ein Iterator immer im Zusammenhang mit einem Container steht. Wenn man die Initialisierung des Iterators mit "NULL" nun aber nur dadurch erreicht, in dem man den Iterator auf .end() eines entsprechenden Containers setzt, so ist das meiner Meinung nach eine Einschränkung, die falsch ist. Es muss doch auch so möglich sein, für einen Iterator abzufragen, ob er überhaupt schon an einen Container gebunden ist, oder noch frei ist. Bei der Beta von VS2008 gibt es dafür ja jetzt beispielsweise die Iteratorfunktion _Has_container() die einem dann true oder false zurückliefert. Nur wie kann man unter VS2005 diesen Zustand des Iterators abfragen, wenn man nicht dieses Konstrukt Iterator = 0 benutzt, um dann später abfragen zu können if(Iterator == 0).

Gruß, Carsten.
das ist so gedacht, iteratoren sind kein pointerersatz, sie sind lediglich dazu da durch container zu iterieren. du kennst also den scope, denn ausserhalb des dir bekannten scopes kannst du garnicht wissen ob der iterator noch gueltig waere, kann ja sein, dass der container nichtmal mehr exisitert, und deswegen kannst du mit ziemlicher gewissheit auf .end() initialisieren.

Trap
2007-09-26, 08:50:26
Nur diese Einschränkung verstehe ich nicht ganz. Syntaktisch ist es nicht erforderlich, dass ein Iterator immer im Zusammenhang mit einem Container steht.
Man kann aber mit solchen Iteratoren nichts mit definiertem Ergebnis machen, außer ihnen einen Iterator zuweisen der mit einem Container in Verbindung steht.

Alles was darüber hinaus geht ist "undefined behaviour" oder compilerspezifische Erweiterung (wenn es in der Doku des Compiler erwähnt ist).

Asmodeus
2007-09-26, 13:31:24
Man kann aber mit solchen Iteratoren nichts mit definiertem Ergebnis machen, außer ihnen einen Iterator zuweisen der mit einem Container in Verbindung steht.

Alles was darüber hinaus geht ist "undefined behaviour" oder compilerspezifische Erweiterung (wenn es in der Doku des Compiler erwähnt ist).

Beudeutet dies also in letzter Konsequenz, man kann zwei Iteratoren auch nur miteinander vergleichen ( == oder != ) wenn sie beide mit dem selben Container verbunden sind? Angenommen, man hat zwei verschiedene Container des selben Typs und verbindet mit jedem dieser Container einen eigenen Iterator, dann können diese beiden Iteratoren nicht miteinander verglichen werden?

Gruß, Carsten.

Coda
2007-09-26, 15:56:55
Ja. Vergleichen von Iteratoren ist nur erlaubt wenn sie auf den gleichen Container zeigen.

Die VC++-2005-STL nölt da auch "iterators are incompatible". Ich hab mir vor 2005 echt lange gewünscht das sowas implementiert wird, dann macht man keine dummen Fehler :)

Xmas
2007-09-26, 16:03:10
Übrigens sollte man eh 0 statt "NULL" bei C++ verwenden. Macros sind böse.
NULL macht manchmal den Code lesbarer (sofern man es nur dort anwendet wo Pointer hinkommen). Macros sind auch nicht generell böse, zumal es nicht in allen Fällen entsprechenden Ersatz gibt.