Zu Testzwecken habe ich ein kleines ungeordnetes_set erstellt und versucht, über das Set zu iterieren. Das Set enthält eine eigene Klasse:
%Vor%Ich habe einige Elemente eingefügt und versucht, die Objekte während der Iteration zu ändern:
%Vor%Ich habe einen local_iterator verwendet (und nicht den const_local_iterator), aber ich kann die Objekte immer noch nicht ändern. Aus bestimmten Gründen verweist der Iterator immer noch auf ein konstantes Objekt.
Meine Frage jetzt: Warum ist das so? Wenn sich der normale Iterator auf ein konstantes Objekt bezieht, was ist der Unterschied zwischen dem const und dem nichtkonstanten Iterator?
Getestet mit VisualStudio 2013 und minGW.
Vielen Dank im Voraus für jede Hilfe: -)
BEARBEITEN: Der Hash-Funktor:
%Vor%Für Finder dieses Themas in der Zukunft, die die gleiche Frage haben, hier ist eine Beispielausgabe, wenn Sie die matrNr mit gewalttätig ändern:
%Vor%und versuchen Sie es anzuzeigen:
%Vor%Sie können etwas wie:
bekommenBucketnummer: 0
Ein leerer Eimer
Bucketnummer: 1
Matrikelnummer: 5
Name: Wilma
Bucketnummer: 2
Ein leerer Eimer
Bucketnummer: 3
Ein leerer Eimer
Buckelnummer: 4
Matrikelnummer: 5
Name: Fred
Buckelnummer: 5
Ein leerer Eimer
Buckelnummer: 6
Matrikelnummer: 5
Name: Barney
Buckelnummer: 7
Ein leerer Eimer
// Die nicht gewünschte Ausgabe; -)
Matrikelnummer: -842150451
Name:
Sowohl set
als auch unordered_set
haben schreibgeschützte Schlüssel. Es ist leicht einzusehen, warum dies der Fall ist - wenn sich der Schlüsselwert ändern würde, würde die Datenstruktur ihn an der falschen Stelle ablegen und Sie könnten ihn nicht mehr finden.
Angenommen, Ihre Hash-Funktion hat einfach das Feld matrNr
zurückgegeben. Wenn sich die Hash-Nummer ändert, wird jede Suche nach 1234
fehlschlagen, da in diesem Hash-Bucket nichts gespeichert ist.
Es könnte möglich sein, einen Teil des Objekts zu ändern, der nicht zum Erstellen des Hash-Schlüssels verwendet wird, aber das könnte dazu führen, dass Fehler nur schwer aufgespürt werden können. Der Normenausschuss beschloss, diese Möglichkeit zu beseitigen, indem der gesamte Schlüssel const.
gemacht wurde Um diese Einschränkung herum gibt es zwei Möglichkeiten. Die erste besteht darin, den Schlüssel vom Wert zu trennen und stattdessen map
oder unordered_map
zu verwenden. Die zweite besteht darin, das Element aus der Gruppe zu entfernen und es nach der Änderung wieder einzufügen.
Sie bewerten den Typ von set<K>
ist const K
und für map<K, T>
ist es pair<const K, T>
; dito für die ungeordneten Versionen.
Ein Iterator gibt Ihnen Zugriff auf value_type &
und einen Const-Iterator auf ein const value_type &
. Wie Sie sehen können, kann keiner der beiden Iteratoren die Konstanz des Schlüssels rückgängig machen.
Der Grund dafür, dass der Schlüssel unveränderbar ist, besteht darin, dass er ein integraler Bestandteil der zugrunde liegenden Datenstruktur ist. das Ändern des Schlüssels würde eine nicht-triviale interne Umordnung erfordern, die alle Arten von Problemen verursachen würde (z. B. eine Rechenkomplexität ungleich null (für den Elementzugriff!) und eine verwirrende Iteratorordnung).
unordered_set ist eine Art von Datenstruktur, in der Sie ein Element nicht ändern können, ohne seinen Speicherort zu ändern.
Nicht-konstanter Iterator ist hier const, weil STL Sie vor solch einem offensichtlichen Fehler schützt.
Wenn Sie das Element eines ungeordneten Eintrags ändern möchten, müssen Sie es entfernen und erneut hinzufügen.
Tags und Links c++ c++11 stl unordered-set