O
Wutz schrieb:
Das ist aber die originale Frage hier gewesen.
Nein? Die Originale Frage war, dass der User zu einem String einen int wert haben wollte. Und das ist nicht die Frage nach der Existenz. Unter der Bedingung, dass die Datei validiert ist, ist die Existenzfrage sogar völlig egal und du schreibst:
map<string,int> mymap;
//...
int color=mymap[mycolorstring];
Und ansonstne benutzt du map::find. Das leistet sowohl die Existenz als auch die Übergabe des Wertes.
Die Key-Folge einer map ist immer ein Set, aber auch beim Set gibts diese Elementarfunktion nicht, stattdessen muss man ein neues Objekt(!) Iterator bzw. bei equal_range sogar ein Paar Iteratoren neu definieren, nur um festzustellen, ob eine map/set einen unique Key nun enthält oder nicht, wobei das equal_range-it-Pair auch wieder redundant ist, da wegen des unique keys einer map der range immer gleich 1 ist. Das ist Sinnfreiheit pur, fehleranfällig und per se inperformant.
1. Ich fürchte dass ein Aufruf von map::end() und operator == exakt gar nichts kostet.
2. Du solltest im Release Modus compilieren.
3. equal_range verwendest du nur im generischen Kontext, wenn du auch eine multimap/ ein multiset erwarten würdest. Der Standard hat sich hier in allen Fällen für ein generisches Interface entschieden, in dem man den einen Typ gegen den anderen leicht austauschen kann. Kannst du als schlechtes Design sehen, aber du kannst mit multimaps eh nichts anfangen.
Ganz schlimm sieht es bei key_comp aus, mit dem man auch nach einem Key suchen kann;
Du hast die map nicht verstanden. key_comp legt fest, wie die Schlüssel verglichen werden um den RB-Baum aufzubauen. Das ist genau dann sinnvoll, wenn es keinen operator< gibt den die Map verwenden kann, oder wenn man eine bestimmte Sortierung zum iterieren braucht. Die Methode key_comp ist nur dazu da, dass selbst bestimmte Schlüssel miteinander verglichen werden können.
(die Key-Indizierung passiert meistens über Hashes und die sind nunmal üblicherweise nicht so sortiert wie ihre Basiswerte, d.h. um die definierte std::map Sortierung sicherzustellen, muss jedesmal (bei jedem Update in der map) die komplette Key-Folge durchsortiert werden).
Die verschämt mit TR1 nachgereichten unordered_map/set zeigen wie es gehen kann, sind aber bekanntlich eben nicht C++98 und somit nicht überall verfügbar.
1. Du hast RB-Bäume nicht verstanden.
2. Du hast hashmaps nicht verstanden.
Irgendwann hat dir wohl mal jemand gesagt, dass hashmaps voll cool sind, hat dir aber verschwiegen, dass die auch durchaus eine ganze Latte von Nachteilen haben. Zum Beispiel kann das einfügen von n Elementen in eine Hashmap in O(n^2) liegen - und Lookup in O(n). Bei der map ist es garantiert in O(n log(n)), bzw log(n), trotz "Sortierung der Keyfolge" (was im Normalfall nur das Umhängen von ein paar Zeigern ist). Es gibt sogar sehr effektive Angriffe auf Webserver, die das ausnutzen.