web-dev-qa-db-de.com

Was passiert, wenn ich den Wert einer Karte lese, wenn der Schlüssel nicht existiert?

map<string, string> dada;
dada["dummy"] = "papy";
cout << dada["pootoo"];

Ich bin verblüfft, weil ich nicht weiß, ob es sich um ein undefiniertes Verhalten handelt oder nicht, wie ich weiß, wann ich einen Schlüssel anfordert, der nicht existiert.

51
jokoon

Der map::operator[] durchsucht die Datenstruktur nach einem Wert, der dem angegebenen Schlüssel entspricht, und gibt einen Verweis darauf zurück.

Wenn es eines nicht finden kann, erstellt es transparent ein standardmäßig erstelltes Element dafür. (Wenn Sie dieses Verhalten nicht möchten, können Sie stattdessen die Funktion map::at verwenden.)

Eine vollständige Liste der std :: map-Methoden finden Sie hier:

http://en.cppreference.com/w/cpp/container/map

Hier ist die Dokumentation von map::operator[] aus dem aktuellen C++ Standard ...

23.4.4.3 Zugriff auf Kartenelemente

T& operator[](const key_type& x);

  1. Auswirkungen: Wenn in der Karte kein Schlüssel vorhanden ist, der x entspricht, wird value_type (x, T()) in die Karte eingefügt.

  2. Erforderlich: key_type muss CopyConstructible sein und mapped_type muss DefaultConstructible sein.

  3. Rückgabe: Ein Verweis auf den mapped_type, der x in * this entspricht.

  4. Komplexität: logarithmisch.

T& operator[](key_type&& x);

  1. Auswirkungen: Wenn in der Karte kein Schlüssel vorhanden ist, der x entspricht, wird value_type (std :: move (x), T()) in die Karte eingefügt.

  2. Benötigt: mapped_type soll DefaultConstructible sein.

  3. Rückgabe: Ein Verweis auf den mapped_type, der x in * this entspricht.

  4. Komplexität: logarithmisch.

61
Andrew Tomazos

Wenn Sie versuchen, mit dem Indexoperator key value auf ein [] zuzugreifen, können zwei Dinge passieren:

  1. Die Karte enthält diese key. Es wird also das entsprechende key value zurückgegeben.
  2. Die Map enthält nicht das key. In diesem Fall wird der Karte automatisch ein key mit null value hinzugefügt.

Der "pootoo"-Schlüssel ist in Ihrer Karte nicht vorhanden. Es wird also automatisch diese key mit value = "" (leere Zeichenfolge) hinzugefügt. Und Ihr Programm druckt eine leere Zeichenfolge.

Hier erhöht sich die Kartengröße um 1.

Um einen Schlüssel zu suchen, können Sie map_name.find() verwenden. Dies gibt map_name.end() zurück, wenn der Schlüssel nicht vorhanden ist. Und es wird kein zusätzliches key hinzugefügt.

Sie können den Operator [] verwenden, wenn Sie einen Wert für einen Schlüssel festlegen möchten.

14
Ali Akber

Es ist kein undefiniertes Verhalten. Wenn operator [] keinen Wert für den bereitgestellten Schlüssel findet, wird an dieser Position ein Wert eingefügt. 

7
Luchian Grigore

Wenn Sie für Operator [] versuchen, auf einen Wert für einen nicht vorhandenen Schlüssel zuzugreifen, wird ein neues Wertobjekt, das standardmäßig erstellt wurde, in die Map eingefügt und dessen Referenz zurückgegeben.

6
Michael Kohne

Der operator[] für map gibt eine Nicht-Konstante-Referenz zurück, und Sie können sie auf die Weise zuweisen, die Sie in der zweiten Zeile angezeigt haben. Wenn Sie auf diese Weise zugreifen, wird ein standardmäßig erstelltes Element vom Typ value erstellt.

Wenn Sie ein Element finden möchten, ist dies ein besserer Weg

iterator find ( const key_type& x )

(oder die const-Alternative), die einen Iterator gleich <map>.end() zurückgibt, wenn der Schlüssel nicht gefunden wird oder wenn Sie nur wissen möchten, ob er in der Sammlung vorhanden ist

size_type count ( const key_type& x ) const

dies gibt immer entweder 1 oder 0 für eine Karte zurück, da die Schlüssel eindeutig sind.

2
Component 10

Wenn Operator [] keinen Wert für den bereitgestellten Schlüssel findet, wird an dieser Position ein Wert eingefügt.

Aber Sie sollten beachten dass, wenn Sie einen not exist key aufrufen und dessen Member-Funktion aufrufen, wie mapKV [not_exist_key] .member_fun ().

Lassen Sie mich ein Beispiel geben, Testklasse wie folgt:

struct MapValue{
    int val;

    MapValue(int i=0){
        cout<<"ctor: "<<i<<endl; val = i;
    }

    ~MapValue(){
        cout<<"dtor: "<<val<<endl;
    }

    friend ostream& operator<<(std::ostream& out, const MapValue& mv){
        cout<<"MapValue: "<<mv.val<<endl;
    }

    string toString(){
        cout<<"MapValue: "<<val<<endl;
    }
};

Testcode:

cout<<"-------create map<int, MapValue>-------"<<endl;

map<int, MapValue> idName{{1, MapValue(1)}, {2, MapValue(2)}};

cout<<"-----cout key[2]-----"<<endl;
cout<<idName[2]<<endl;

cout<<"-----cout key[5]-----"<<endl;
cout<<idName[5]<<endl;

cout<<"------- runs here means, does't crash-------"<<endl;

Ausgabe wie folgt:

-------create map<int, MapValue>-------
ctor: 1
ctor: 2
dtor: 2
dtor: 1
dtor: 2
dtor: 1
-----cout key[2]-----
MapValue: 2

-----cout key[5]-----
ctor: 0
MapValue: 0

-------runs here means, does't crash-------
dtor: 0
dtor: 2
dtor: 1

Wir können Folgendes sehen: idName[5] ruft das Map-Konstrukt {5, MapValue(0)} auf, um es in idName einzufügen.

Wenn Sie jedoch die Memberfunktion über idName[5] aufrufen, stürzt das Programm ab:

cout<<"-------create map<int, MapValue>-------"<<endl;

map<int, MapValue> idName{{1, MapValue(1)}, {2, MapValue(2)}};


idName[5].toString();  // get crash here.


cout<<"------- runs here means, does't crash-------"<<endl;
1
Jayhello

bitte sehen Sie sich die Ausnahme out_of_range an: http://www.cplusplus.com/reference/stdexcept/out_of_range/

dies ist, was map :: at und map :: operator [] auslösen wird, wenn der Schlüssel nicht vorhanden ist. Sie können es genauso wie das Vektorbeispiel in der Verknüpfung abfangen.

Sie können auch Folgendes verwenden: http://www.cplusplus.com/reference/map/map/find/

Und gegen map :: ende prüfen

0
user2346536