2009-05-10 11 views
9

Ich frage mich, wie ist die Gleichheit (==) für STL-Iteratoren? Ist es ein einfacher Zeiger Vergleich (und damit auf Adressen) oder etwas mehr Phantasie?Wie wird die STL-Iteratorgleichheit eingerichtet?

Wenn ich zwei Iteratoren von zwei verschiedenen Listenobjekten habe und ich vergleiche, wird das Ergebnis immer falsch sein?

Wie wäre es, wenn ich einen gültigen Wert mit einem außerhalb des gültigen Bereichs vergleichen würde? Ist das immer falsch?

Antwort

11

Iterator-Klassen können überladene == Operatoren definieren, wenn sie möchten. Das Ergebnis hängt also von der Implementierung von operator== ab.

Sie sollten nicht wirklich Iteratoren aus verschiedenen Containern vergleichen. Ich denke, dass einige Debug-STL-Implementierungen eine Warnung signalisieren, wenn Sie dies tun, was Ihnen helfen wird, Fälle dieser fehlerhaften Verwendung in Ihrem Code zu erkennen.

+6

Eigentlich nicht zu? Das musst du bestimmt nicht! – xtofl

+0

Die Möglichkeit, Iteratoren aus verschiedenen Containern technisch zu vergleichen, führt dazu, dass MSVC bei Verwendung von 'std :: copy' ... eine lästige Verwarnungswarnung ausgibt ... –

2

Ich frage mich, wie ist die Gleichheit (==) für STL-Iteratoren?

Nicht alle Iteratoren können verglichen werden (z. B. Ausgabe-Iteratoren müssen op== nicht liefern). Sie können operator== verwenden, wenn das Konzept eines Bereichs für die betrachtete Iteratorkategorie klar definiert ist.

Ist es ein einfacher Zeiger Vergleich (und damit auf Adressen) oder etwas mehr Phantasie?

Iteratoren werden immer mit Zeigern implementiert. Edit: Ich sage implementiert mit - das bezieht sich nicht auf eine Standardanforderung, sondern eher auf die Praxis der Verwendung poitners als zugrunde liegendes Konstrukt. Bei Implementierungen (wie VS) können jedoch spezielle Validierungsprüfungen eingefügt werden.

Wenn ich zwei Iteratoren von zwei verschiedenen Listenobjekten habe und ich vergleiche, wird das Ergebnis immer falsch sein?

Sie rufen Undefined Behavior auf.

Was ist, wenn ich einen gültigen Wert mit einem Wert außerhalb des Bereichs vergleiche? Ist das immer falsch?

Auch hier werden Sie UB aufrufen. Der einzige gültige Vergleich besteht zwischen zwei Iteratoren im selben Bereich oder zwischen einem im Bereich und einem anderen bis zum letzten Element. Beachten Sie, dass Sie nur gegen den Iterator mit einem nach dem letzten Element vergleichen können, indem Sie die gleichen Leads auf UB dereferenzieren.

+4

" Iteratoren werden immer als Zeiger implementiert ". Ich glaube nicht, dass insert_iterator ein einfacher Zeiger ist.Ich würde erwarten, dass es sich um ein Objekt handelt, das einen Zeiger oder Verweis auf einen Container enthält, sowie einen Iterator für diesen Container. –

+0

Nachschlagen. Die Implementierungen, die ich gesehen habe, verwenden einen Zeiger auf den Container. – dirkgently

+2

Nur std :: vector :: iterator ist garantiert in einen Zeiger konvertierbar. Viele wahrscheinlich _use_ Zeiger auf ihre Knoten. Manche benutzen zwei Zeiger. Einige können einen Dateizeiger verwenden. Können Sie dann behaupten, dass sie als Zeiger implementiert sind? Ich denke nicht. Ich würde es nicht wagen, irgendein Design darauf zu basieren. – xtofl

1

Der Gleichheitstest ist spezifisch für den Typ des Iterators, den Sie verwenden, oder möglicherweise gar nicht. Wenn Sie das wirklich wissen wollen, können Sie immer den Quellcode der verwendeten STL-Implementierung überprüfen, suchen Sie in der Iterator-Klasse nach operator ==().

Iteratoren sind NICHT immer Zeiger, und tatsächlich in einigen "sicheren" Versionen der STL, sind nie Zeiger. Iteratoren für Vektoren und Zeichenfolgen werden üblicherweise als Zeiger implementiert, weil sie dies können. Iteratoren für Deques, Listen, Mengen und Karten können keine Pointer in irgendeiner halb effizienten Implementierung sein.

Was Iteratoren sind, ist eine Art von Smart Pointer. Sie folgen dem generischen Prinzip, dass sie, wenn sie wie ein Zeiger aussehen und sich verhalten, einen Zeiger sind, soweit der Benutzer betroffen ist.

3

fragte Daniel: Ich habe mich gefragt, wie die Gleichheit (==) für STL Iteratoren etabliert? Ist es ein einfacher Zeigervergleich (und damit auf Adressen basierend) oder etwas ausgefallener?

Es hängt von der Implementierung ab. Gerade jetzt, auf Visual C++ 2008, sehe ich den folgenden Code (für die Liste Iterator):

bool operator==(const _Myt_iter& _Right) const 
{ // test for iterator equality 

#if _HAS_ITERATOR_DEBUGGING 
    _Compat(_Right); 
#else 
    _SCL_SECURE_TRAITS_VALIDATE(this->_Has_container() && this->_Same_container(_Right)); 
#endif /* _HAS_ITERATOR_DEBUGGING */ 

    return (_Ptr == _Right._Ptr); 
} 

Sie oben sehen werden, dass es sowohl Code für die Überprüfung der Iterator Gültigkeit und _Ptr ist ein Zeiger auf ein Listenknoten.

Also ich denke, es gibt sowohl Verifikation, als auch einfache, rohe Zeiger Vergleich.

fragte Daniel: Wenn ich zwei Iteratoren aus zwei verschiedenen Listenobjekte und ich vergleiche sie, wird das Ergebnis immer falsch sein?

Bis jetzt scheint es, dass der Standard zu diesem Thema etwas unklar war. Anscheinend wird sie explizit schreiben, dass diese Art von Operation Ergebnisse nicht definiert hat:

Zitiert: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#446

Das Ergebnis unter Verwendung eines beliebigen Iterator Betrieb (24.2.1 [input.iterators], 24.2.2 [output.iterators], 24.2.3 [forward.iterators], 24.2.4 [bidirektionale.iterators], 24.2.5 [random.access.iterators]) die zwei Iteratorwerte als Argumente verwendet (Fußnote) die waren aus zwei verschiedenen Bereichen erhalten r1 und r2 (einschließlich ihrer Vergangenheit-am-Ende-Werte), die nicht Teilbereiche eines gemeinsamen Bereichs sind ist nicht definiert, sofern nicht explizit anders beschrieben.

Fußnote) Unter anderem sind diese Operationen ==, <, binär - und kopieren Zuordnung

Also ich denke, es ist böse Iterator aus verschiedenen Behältern vergleichen ... ^ _^

Daniel fragte: Was ist, wenn ich einen gültigen Wert mit einem Wert außerhalb des Bereichs vergleiche? Ist das immer falsch?

Wie oben.

Verwandte Themen