2017-11-28 11 views
0

ここに私のコードです。私はELEM構造体のためのリファレンスを使用する場合はマイマップは、そうでない場合、私は正しい値を取得し、空になります。C++なぜ参照を使用する場合、私のマップ<string、string>を空にするのですか?

#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; 
} 

あなたは私を説明でき、問題は何ですか? おかげ&

+0

私はVisual Studioを使用しています2015 – barnus1983

+3

あなたは今破壊された要素をポップしました。 –

+0

要素を固定するには、elem2を 'const ELEM&'にする必要があります。それ以外の場合は、それは不快です。あなたは 'ポップ 'の後に破壊された価値を得ている –

答えて

0

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

elem2elem1への参照です。 2行目でpop()を呼び出すと、elem1がスタックから削除されて破棄され、elem2とダングリングリファレンスが作成されます。 elem2.Attributes.size()を呼び出すと、0が返されます。elem2は、破棄されたelem1を意味します。0を返してきましたが、動作は未定義です。何が起きるかは保証されていません(これを指摘してくれたCalethに感謝します)。 &なし

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

elem2は、それが値elem1と同じ値に設定された新しいELEMインスタンス、すなわちelem1のコピーです。 pop()を呼び出すと、elem1がスタックから削除され、以前と同じように破棄されますが、elem2はまだ存在します。 elem2.Attributes.size()を呼び出すと2が返されます。elem2は(今は破棄された)elem1のコピーであるためです。

+1

"elem2.Attributes.size()を呼び出すと、定義されていない動作と一貫しているので、0を返します。最初の例の何らかの*の部分が何を保証するものではありません。 – Caleth

+0

@Calethはい、もちろん、それははるかに理にかなっています。それを指摘してくれてありがとう、今編集する。 – scrpy

+0

ありがとう! "HRMLノード= std :: move(elements.top());"効率的かつエレガントなソリューションですか? – barnus1983

関連する問題