2017-11-28 4 views
0

Hier ist mein Code. Meine Karte ist leer, wenn ich Referenz für ELEM Struktur verwenden, sonst i richtigen Wert erhalten:C++ warum leere meine map <string, string> wenn ich referenz verwende?

#include <cmath> 
#include <cstdio> 
#include <stack> 
#include <map> 
#include <iostream> 
#include <string> 

using namespace std; 

struct ELEM; 

struct ELEM { 
    map<string, ELEM> Children; 
    map<string, string> Attributes; 
}; 

int main() { 

    stack<ELEM> elements; 
    ELEM root; 
    elements.push(root); 

    ELEM elem1; 
    elements.push(elem1); 
    elements.top().Attributes["attr1"] = "val1"; 
    elements.top().Attributes["attr2"] = "val2"; 

    ELEM &elem2 = elements.top(); // here is the problem ??? 
    elements.pop(); 
    elements.top().Children["child1"] = elem2; 

    cout << elements.top().Children["child1"].Attributes.size() << endl; 
    // i get '0' 

    return 0; 
} 

Können Sie mir erklären, was ist das Problem? Dank

+0

Ich benutze Visual Studio 2015 – barnus1983

+3

Sie poppe das Element, das jetzt zerstört ist, und Sie haben eine baumelnde Referenz. –

+0

Wenn Sie das Element anheften wollen, müssen Sie elemm2 'const ELEM &' machen. Weil es sonst verschwindet. Du bekommst rvalue, der nach 'pop' zerstört wird. –

Antwort

0

Mit dem &:

ELEM &elem2 = elements.top(); 
elements.pop(); 

elem2 ist ein Verweis auf elem1. In der zweiten Zeile ruft pop()elem1 aus dem Stapel und zerstört es, wodurch elem2 und baumelnde Referenz. Der Aufruf elem2.Attributes.size() ergibt 0, da sich elem2 auf elem1 bezieht, das zerstört wurde. hat 0 für Sie zurückgegeben, aber das Verhalten ist nicht definiert - es gibt keine Garantie, was passieren wird (Dank Caleth für das Aufzeigen dieser).

Ohne die &:

ELEM elem2 = elements.top(); 
elements.pop(); 

elem2 ist eine Kopie von elem1, das heißt, es ist ein neues ELEM Beispiel, deren Werte auf die gleichen Werte wie elem1 eingestellt. Der Aufruf pop() entfernt elem1 aus dem Stapel und zerstört es wie zuvor, aber elem2 ist noch vorhanden. Der Aufruf elem2.Attributes.size() gibt 2 zurück, da elem2 eine Kopie des (jetzt zerstörten) elem1 ist.

+1

"Aufruf elem2.Attributes.size() gibt 0" zurück, weil das mit undefiniertem Verhalten konsistent ist. Es gibt keine Garantie dafür, was * irgendein * Teil des ersten Beispiels tut. – Caleth

+0

@Caleth Ja, das macht natürlich viel mehr Sinn. Danke, dass du das herausgebracht hast, werde jetzt editieren. – scrpy

+0

Danke! Als "HRML-Knoten = std :: move (elements.top());" ist eine effiziente und elegante Lösung? – barnus1983

Verwandte Themen