2016-10-07 2 views
0

Ich bin neu in C++ Umfang und irgendwie verwirrt über die Lebensdauer eines std::string, wenn es in eine std::map eingefügt wird.Umfang der std :: string wenn in Karte

Zum Beispiel:

void loadMap(std::map<string, int> &myMap) 
{ 
    int num = rand(); 
    myMap[to_string(num) + "_xyz"] = num; 
} 

void main(int argc, char** argv) 
{ 
    std::map<string, int> myMap; 
    loadMap(myMap); 

    //Is the entry I just added to the map in loadMap still safe in there? 
    //i.e., is the key, which is an std::string, still around? 
    //Or its lifetime's ended? 
} 

Ich habe einige Tests und es SCHEINT in Ordnung zu sein, aber ich bin nicht sicher, ob es immer der Fall sein wird. Vielleicht hatte ich nur Glück, dass die Erinnerung, wo die std :: string nicht berührt wurde.

+0

Die Lebensdauer eines Karteninhalts entspricht der Lebensdauer der Karte. – molbdnilo

+0

@Treycos Ich verstehe, dass 'loadMap' die Karte DIREKT geändert hat, weil ich als Referenz weitergegeben habe, ABER was, wenn die Lebensdauer der Zeichenfolge abgelaufen ist? – 0x56794E

+0

Die Antwort ist über – Treycos

Antwort

2

wird die folgende Operation eine std::string rvalue

to_string(num) + "_xyz" 

Da die für die Key Typ map erstellen std::stringvon Wert ist dann wird dies rvalue effektiv in die Karte verschoben werden. In diesem Fall sind Sie in Sicherheit. Die Karte "besitzt" nun diese Zeichenfolge. Daher ist die Lebensdauer der Zeichenfolge die gleiche wie die der Karte in main

+0

In Ordnung. Cool! Danke für die SUPER schnelle Antwort! – 0x56794E

+0

_ "Die folgende Operation wird einen std :: string && rvalue Verweis erstellen" _ Nein wird es nicht. Es wird eine 'std :: string '([keine Verweise] (http://en.cppreference.com/w/cpp/string/basic_string/operator%2B)) erstellt, und der Ausdruck hat eine rvalue-Kategorie. Der Rest ist korrekt. –

+0

@LightnessRacesinOrbit Mein Fehler, du bist richtig – CoryKramer

1

Keine Sorge, die Karte ist sicher, alle Einträge haben gültige Werte.

Wenn Sie std::map::operator[] betrachten, sehen Sie, dass der Schlüssel entweder sein muss:

  • CopyConstructible den Fall, dass für diesen Schlüssel der Schlüssel/Wert-Paar nicht vorhanden ist (und/oder der Schlüssel nicht bewegt wird)
  • MoveConstructible in dem Fall, kann der Schlüssel bewegt werden, ohne dass Kopien zu machen

Dies hat einen Grund: die Behälter kopiert (oder verschieben) der Schlüssel zu speichern. Es wird kein Zeiger oder Verweis gespeichert, wenn der Schlüssel nicht existiert.

Das Gleiche gilt für den Wert: Es ist ein Verweis auf einen Wert bereits in der Karte gespeichert sind, und so, wenn Sie tun

myMap[to_string(num) + "_xyz"] = num; 

Sie num bis auf den internen Wert des Behälters zu kopieren sind.

+1

Eine Kopie hier ist extrem unwahrscheinlich. –

+0

@LightnessRacesinOrbit Richtig :) Danke – Rakete1111

+0

Oh und 'CopyConstructible' ist falsch; Sie müssen auf Definition # 2 schauen –

Verwandte Themen