【问题标题】:c++ why empty my map<string, string> if I use reference?c++ 如果我使用引用,为什么要清空我的 map<string, string>?
【发布时间】:2017-11-28 11:15:36
【问题描述】:

这是我的代码。如果我使用 ELEM 结构的引用,我的地图将为空,否则我得到正确的值:

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

你能解释一下,有什么问题吗? 谢谢

【问题讨论】:

  • 我使用 Visual Studio 2015
  • 你弹出了现在被破坏的元素并且你有一个悬空引用。
  • 如果你想固定元素,你必须制作 elem2 const ELEM &amp;。因为否则它会消散。您将获得在 pop 之后被销毁的右值
  • @AA 这是灾难性的糟糕建议。 const 表示您无法通过引用 elem2 更改对象。这并不意味着它会被保留。您是否在考虑可以使用临时变量初始化 const 引用的情况,在这种情况下临时变量的生命周期会延长?在这种情况下不适用 - top 返回一个引用,而不是临时的。
  • "const ELEM &" 错误。我也失去了内部结构......“ELEM elem2 = elements.top();”正在工作,但它是复制(?),有什么优雅的方法吗?

标签: c++ reference


【解决方案1】:

&amp;

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

elem2 是对elem1 的引用。在第二行调用pop() 从堆栈中删除elem1 并销毁它,使elem2 和悬空引用。调用elem2.Attributes.size() 会返回0,因为elem2 指的是elem1,它已被销毁。 恰好为您返回了0,但行为未定义——无法保证将会发生什么(感谢 Caleth 指出这一点)。

没有&amp;:

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

elem2elem1 的副本,即它是一个新的ELEM 实例,其值已设置为与elem1 相同的值。调用pop() 会从堆栈中删除elem1 并将其销毁,与之前一样,但elem2 仍然存在。调用elem2.Attributes.size() 返回2,因为elem2 是(现已销毁)elem1 的副本。

【讨论】:

  • "调用 elem2.Attributes.size() 返回 0",因为这与未定义的行为一致。无法保证第一个示例的 any 部分的作用。
  • @Caleth 是的,当然,这更有意义。感谢您指出这一点,现在将进行编辑。
  • 谢谢!比“HRML 节点 = std::move(elements.top());”是高效优雅的解决方案吗?
  • 是的,我想是的。例如,请参阅this post
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-05
  • 1970-01-01
  • 1970-01-01
  • 2019-12-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多