std::map<int, float>und std::map<const int, float>sind in ähnlicher Weise verschiedene Typen.
Der Unterschied zwischen std::map<const int, float>und std::map<int, float>ist bis zu einem gewissen Grad analog zu dem Unterschied zwischen beispielsweise std::map<int, float>und std::map<std::string, float>; Sie erhalten jeweils einen neuen Kartentyp.
Im Nichtfall constist der interne Schlüsseltyp immer noch nicht constint:
std::map<constint, float>::key_type => constintstd::map<int, float>::key_type => int
Kartenschlüssel sind jedoch semantisch unveränderlich, und alle Kartenoperationen , die den direkten Zugriff auf Schlüssel ermöglichen (z. B. Dereferenzieren von Iteratoren, was ergibt value_type), führen constFolgendes aus key_type:
So ist der Unterschied kann in jeder Hinsicht Sie weitgehend unsichtbar sein , dass Angelegenheiten, wenn Ihre Implementierung zulässt.
Dies ist jedoch nicht immer der Fall: Der Standard verlangt offiziell, dass Ihr Schlüsseltyp kopierbar und verschiebbar ist, und einige Implementierungen verwenden Kartenknoten wieder . Unter diesen Implementierungen constfunktioniert der Versuch, einen Schlüssel zu verwenden, einfach nicht.
So the difference is largely invisible to you in every way that matters.- es sei denn, Sie verwenden eine stdlib, die Schlüssel kopiert / verschiebt (wie libc ++). In diesem Fall bricht die const-Version nur. Eine entsprechende Diskussion finden Sie unter lists.cs.uiuc.edu/pipermail/cfe-dev/2011-July/015926.html .
@LightnessRacesinOrbit "Der Standard verlangt offiziell, dass Ihr Schlüsseltyp kopierbar und beweglich ist". In Bezug auf die Beweglichkeit kann ich nicht feststellen, dass Sie auf der C ++ - Standardkopie, die ich habe, bitte eine Referenz- oder Abschnittsnummer angeben können.
Beren
Dies ist eine ausgezeichnete Antwort, die schließlich das constProblem der Gesamtheit mit Karten verdeutlichte . C ++ 14 führte die transparenten Komparatoren ein, die ein wenig Komplexität hinzufügen, nur um uns scharf zu halten :)
vsoftco
Ah, danke, dass Sie bestätigt haben, dass Schlüssel nicht const sein dürfen. Ich wollte, dass meine Schlüssel unveränderlich sind und es hat mich verrückt gemacht -_-
Noel Widmer
36
Der Schlüssel ist bereits vorhanden const, daher ist das Schreiben constin diesem Fall überflüssig . Sobald ein Element eingegeben wurde, keykann es nicht mehr geändert werden.
Bearbeiten :
Wie in den Kommentaren erwähnt, gibt es einen Unterschied zwischen den beiden Zeilen. Wenn Sie beispielsweise eine Funktion schreiben, die akzeptiert map<const int, int>, können Sie sie nicht übergeben, map<int, int>da es sich um verschiedene Typen handelt .
Beachten Sie jedoch, dass sie sich, obwohl sie unterschiedliche Typen sind, gleich verhalten, da der Schlüssel in einer Karte constsowieso ein ...
Also abschließend. Der einzige Unterschied ist, dass es sich um zwei verschiedene Typen handelt. Sie sollten sich um nichts anderes kümmern.
Dies ist nicht (vollständig) korrekt. Die Schnittstelle von std::mapmacht den Schlüsseltyp als verfügbar const, aber das bedeutet nicht, dass die beiden Vorlageninstanziierungen identisch sind, wie diese Antwort möglicherweise impliziert. std::map<const int, float>und std::map<int, float>sind verschiedene Arten .
Jrok
1
@jrok ist korrekt, diese Antwort jedoch nicht. Das key_typeist in der Tat noch intim ersteren Fall.
Leichtigkeitsrennen im Orbit
6
@ johnmac2332: Lass dies eine Lektion sein, die so schnell ist! = perfekt und positiv! = richtig.
Leichtigkeitsrennen im Orbit
1
@ johnmac2332 Schnelle und schnelle Antworten sollten sehr geschätzt werden. Dies ist einer der hochwertigen Stackoverflow besser als andere Bahnen. OP kann im Kommentarbereich weiter abfragen. Wenn er Danke sagt, hat er wahrscheinlich die Antwort bekommen.
Grijesh Chauhan
2
Niemand ist perfekt, wir alle machen Fehler und lernen voneinander. Wir sind hier, um zu lernen und zu helfen :)
Maroun
8
Der Unterschied besteht darin, dass die zweite Variante den Schlüsseltyp für die Karte als festlegt const int. Unter dem Gesichtspunkt der "Modifizierbarkeit" ist dies redundant, da die Karte ihre Schlüssel bereits als speichertconst Objekte .
Dies kann jedoch auch zu unerwarteten und nicht offensichtlichen Unterschieden im Verhalten dieser beiden Karten führen. In C ++ unterscheidet sich eine für Typ geschriebene Vorlagenspezialisierung von einer für Typ Tgeschriebenen Spezialisierung const T. Das bedeutet, dass die beiden oben genannten Versionen der Karte möglicherweise unterschiedliche Spezialisierungen verschiedener "Satelliten" -Vorlagen verwenden, die vom Schlüsseltyp abhängen. Ein Beispiel ist das Schlüsselkomparator-Prädikat. Der erste wird verwendet, std::less<int>während der zweite verwendet wirdstd::less<const int> . Indem Sie diesen Unterschied ausnutzen, können Sie diese Karten einfach erstellen, um ihre Elemente in unterschiedlicher Reihenfolge zu sortieren.
Probleme wie diese sind bei den neuen C ++ 11-Containern wie z std::unordered_map. std::unordered_map<const int, int>wird nicht einmal kompiliert, da versucht wird, eine std::hash<const int>Spezialisierung zum Hashing der Schlüssel zu verwenden. Eine solche Spezialisierung gibt es in der Standardbibliothek nicht.
constkann nach dem Einstellen nicht mehr geändert werden. Und ja, laut Dokumentation und anderer Antwort sollten Sie sich daran erinnern, dass dies bereits der Fall keyist const.
Entschuldigung, ich sollte schreiben - kann nicht. Mods haben bearbeitet - Danke
Shumail
2
Während das Verhalten Ihrer Anwendung normalerweise das gleiche ist, macht es für einige Compiler, die Sie möglicherweise verwenden, einen Unterschied. Das spezifischere Beispiel dafür, was mich überhaupt auf diese Seite gebracht hat:
Explizite Angabe einer Karte als map<const key, value> Builds erfolgreich mit dem gnu-Toolkit;
Ein Studio12 Solaris x86-Build stürzt jedoch ab.
map<key, value>baut erfolgreich auf beiden auf. Das Verhalten der Anwendung bleibt unverändert.
@LightnessRacesinOrbit Es wurde über std::map::insertmehrere Deklarationen geklagt .
7.
Ja, wie oben erwähnt: Es macht einen Unterschied für den Compiler.
7.
Wenn wir "Absturz" sagen, beziehen wir uns normalerweise auf eine unerwartete und unansehnliche Laufzeitbeendigung eines Prozesses. Compiler-Abstürze sind selten, treten jedoch auf (insbesondere bei neuen Sprachfunktionen) und sind sehr schwerwiegend (je nach Erstellungsergebnissen).
Leichtigkeitsrennen im Orbit
Es stürzt mein Build ab , nicht die Anwendung . Missbrauche ich die Terminologie?
7.
0
Const-Schlüssel können hilfreich sein, wenn die Schlüssel Zeiger sind. Wenn Sie const-Schlüssel verwenden, können Sie das spitze Objekt beim Zugriff auf die Schlüssel nicht ändern. Beachten Sie Folgendes:
Wenn das key_typeist const int*, ist der Zeiger selbst nicht const, aber der spitze intist const.
Lrineau
-1
const bezieht sich auf eine Konstante, die, sobald sie definiert ist, nicht mehr geändert werden kann. und "Änderung" kann in nicht konstanten Sachen auftreten oder nicht.
Antworten:
int
undconst int
sind zwei verschiedene Typen.std::map<int, float>
undstd::map<const int, float>
sind in ähnlicher Weise verschiedene Typen.Der Unterschied zwischen
std::map<const int, float>
undstd::map<int, float>
ist bis zu einem gewissen Grad analog zu dem Unterschied zwischen beispielsweisestd::map<int, float>
undstd::map<std::string, float>
; Sie erhalten jeweils einen neuen Kartentyp.Im Nichtfall
const
ist der interne Schlüsseltyp immer noch nichtconst
int
:std::map<const int, float>::key_type => const int std::map<int, float>::key_type => int
Kartenschlüssel sind jedoch semantisch unveränderlich, und alle Kartenoperationen , die den direkten Zugriff auf Schlüssel ermöglichen (z. B. Dereferenzieren von Iteratoren, was ergibt
value_type
), führenconst
Folgendes auskey_type
:std::map<const int, float>::value_type => std::pair<const int, float> std::map<int, float>::value_type => std::pair<const int, float>
So ist der Unterschied kann in jeder Hinsicht Sie weitgehend unsichtbar sein , dass Angelegenheiten, wenn Ihre Implementierung zulässt.
Dies ist jedoch nicht immer der Fall: Der Standard verlangt offiziell, dass Ihr Schlüsseltyp kopierbar und verschiebbar ist, und einige Implementierungen verwenden Kartenknoten wieder . Unter diesen Implementierungen
const
funktioniert der Versuch, einen Schlüssel zu verwenden, einfach nicht.quelle
So the difference is largely invisible to you in every way that matters.
- es sei denn, Sie verwenden eine stdlib, die Schlüssel kopiert / verschiebt (wie libc ++). In diesem Fall bricht die const-Version nur. Eine entsprechende Diskussion finden Sie unter lists.cs.uiuc.edu/pipermail/cfe-dev/2011-July/015926.html .const
Problem der Gesamtheit mit Karten verdeutlichte . C ++ 14 führte die transparenten Komparatoren ein, die ein wenig Komplexität hinzufügen, nur um uns scharf zu halten :)Der Schlüssel ist bereits vorhanden
const
, daher ist das Schreibenconst
in diesem Fall überflüssig . Sobald ein Element eingegeben wurde,key
kann es nicht mehr geändert werden.Bearbeiten :
Wie in den Kommentaren erwähnt, gibt es einen Unterschied zwischen den beiden Zeilen. Wenn Sie beispielsweise eine Funktion schreiben, die akzeptiert
map<const int, int>
, können Sie sie nicht übergeben,map<int, int>
da es sich um verschiedene Typen handelt .Beachten Sie jedoch, dass sie sich, obwohl sie unterschiedliche Typen sind, gleich verhalten, da der Schlüssel in einer Karte
const
sowieso ein ...Also abschließend. Der einzige Unterschied ist, dass es sich um zwei verschiedene Typen handelt. Sie sollten sich um nichts anderes kümmern.
quelle
std::map
macht den Schlüsseltyp als verfügbarconst
, aber das bedeutet nicht, dass die beiden Vorlageninstanziierungen identisch sind, wie diese Antwort möglicherweise impliziert.std::map<const int, float>
undstd::map<int, float>
sind verschiedene Arten .key_type
ist in der Tat nochint
im ersteren Fall.Der Unterschied besteht darin, dass die zweite Variante den Schlüsseltyp für die Karte als festlegt
const int
. Unter dem Gesichtspunkt der "Modifizierbarkeit" ist dies redundant, da die Karte ihre Schlüssel bereits als speichertconst
Objekte .Dies kann jedoch auch zu unerwarteten und nicht offensichtlichen Unterschieden im Verhalten dieser beiden Karten führen. In C ++ unterscheidet sich eine für Typ geschriebene Vorlagenspezialisierung von einer für Typ
T
geschriebenen Spezialisierungconst T
. Das bedeutet, dass die beiden oben genannten Versionen der Karte möglicherweise unterschiedliche Spezialisierungen verschiedener "Satelliten" -Vorlagen verwenden, die vom Schlüsseltyp abhängen. Ein Beispiel ist das Schlüsselkomparator-Prädikat. Der erste wird verwendet,std::less<int>
während der zweite verwendet wirdstd::less<const int>
. Indem Sie diesen Unterschied ausnutzen, können Sie diese Karten einfach erstellen, um ihre Elemente in unterschiedlicher Reihenfolge zu sortieren.Probleme wie diese sind bei den neuen C ++ 11-Containern wie z
std::unordered_map
.std::unordered_map<const int, int>
wird nicht einmal kompiliert, da versucht wird, einestd::hash<const int>
Spezialisierung zum Hashing der Schlüssel zu verwenden. Eine solche Spezialisierung gibt es in der Standardbibliothek nicht.quelle
const
kann nach dem Einstellen nicht mehr geändert werden. Und ja, laut Dokumentation und anderer Antwort sollten Sie sich daran erinnern, dass dies bereits der Fallkey
istconst
.Link: http://www.cplusplus.com/reference/map/map/ Link: http://en.cppreference.com/w/cpp/container/map
quelle
Während das Verhalten Ihrer Anwendung normalerweise das gleiche ist, macht es für einige Compiler, die Sie möglicherweise verwenden, einen Unterschied. Das spezifischere Beispiel dafür, was mich überhaupt auf diese Seite gebracht hat:
Explizite Angabe einer Karte als
map<const key, value>
Builds erfolgreich mit dem gnu-Toolkit;Ein Studio12 Solaris x86-Build stürzt jedoch ab.
map<key, value>
baut erfolgreich auf beiden auf. Das Verhalten der Anwendung bleibt unverändert.quelle
std::map::insert
mehrere Deklarationen geklagt .Const-Schlüssel können hilfreich sein, wenn die Schlüssel Zeiger sind. Wenn Sie const-Schlüssel verwenden, können Sie das spitze Objekt beim Zugriff auf die Schlüssel nicht ändern. Beachten Sie Folgendes:
#include <map> #include <string> int glob = 10; int main() { std::map<const int*, std::string> constKeyMap { { &glob, "foo"} }; std::map<int*, std::string> keyMap { { &glob, "bar" } }; for(const auto& kv : keyMap) { *(kv.first) = 20; }; // glob = 20 for(const auto& kv : constKeyMap) { *(kv.first) = 20; }; // COMPILE ERROR return 0; }
quelle
key_type
istconst int*
, ist der Zeiger selbst nicht const, aber der spitzeint
ist const.const bezieht sich auf eine Konstante, die, sobald sie definiert ist, nicht mehr geändert werden kann. und "Änderung" kann in nicht konstanten Sachen auftreten oder nicht.
quelle