【问题标题】:C++ Storing references to values in std::mapC++ 在 std::map 中存储对值的引用
【发布时间】:2023-03-27 08:55:01
【问题描述】:

我是否正确假设向 std::map 添加/删除元素不会影响其他元素(即导致它们在内存中重新定位),因此以下内容是安全的:

我查看了有关容器信息的各个站点,但只发现了迭代器无效的情况,我已经知道了......

std::map<std::string,std::string> map;
PopulateMap(map);
std::string &a= map["x"];
AddMoreData(map);
RemoveRandomKeysExceptX(map);
map["x"] = "foo";
std::cout << a << " " << map["x"] << std::endl;//prints "foo foo"
a = "bar";
std::cout << a << " " << map["x"] << std::endl;//prints "bar bar"

我在 VC9 上测试了一些类似的代码,这似乎可以工作,但这并不意味着我不只是幸运,也不意味着它不会因编译器而异。

【问题讨论】:

  • 不知道为什么你删除了你的答案 nadeen,据我所知它是正确的。
  • naveen 的回答是关于迭代器,这个问题不是
  • 我也删除了我的答案,因为在二读时我完全不清楚实际问题是什么。
  • 完全重复:正如 litb 指出的那样:stackoverflow.com/questions/516007/…

标签: c++ reference stdmap


【解决方案1】:

23.1.2/8 中关于关联容器的标准对此很清楚

插入成员不会影响迭代器的有效性和对容器的引用,而擦除成员只会使迭代器和对被擦除元素的引用无效。

【讨论】:

  • +1。我需要保留一份标准副本。我的回答本来可以更简洁明确。
  • 是的,保持 okular / acroread 实例打开总是一个好主意,这样您就可以快速查找内容 =) 在这种情况下,我记得我在这里的讨论:stackoverflow.com/questions/516007/… =)跨度>
  • 我鼓励您在那里投票支持@greg-rogers 的答案。因为它是正确的,显然,而公认的答案说你不能确定这一点。但标准非常明确,指针始终有效。
  • 看答案你在说哪一个,我没有看到“greg-rogers”...
  • 我的意思是我链接到的问题,上面:)
【解决方案2】:

Map 有一个重要的属性,即在 map 中插入一个新元素不会使指向现有元素的迭代器失效。 引用自sgi docs

如果保证迭代器不会改变,那么它们指向的值也不会改变。

naveen 之前有一个类似的答案。除非我的逻辑有错误,否则您所做的事情是安全的。

编辑 2: 请参阅sgi docs 中的第 3 点,了解从运算符 [] 获取值与从迭代器获取值的相同之处。

【讨论】:

  • 正如我向 naveen(不是 nadeen)指出的那样,问题不在于迭代器。
  • 我知道,但是 operator [] 使用迭代器。
  • 请注意,在细节方面,SGI 文档有时与标准库存在细微差异。
【解决方案3】:

是的,您可以信赖这一点。

// retrieve reference to string stored at "x"
// note that since [] returns a reference, it must insert an element at "x" if 
// it doesn't exists (in this case an empty string)
std::string &a= map["x"];

// retrieve reference for "x" again and set value to "foo"
map["x"] = "foo";

// use already stored reference
a = "bar";

【讨论】:

    猜你喜欢
    • 2010-12-05
    • 1970-01-01
    • 2010-10-06
    • 1970-01-01
    • 2022-11-21
    • 1970-01-01
    • 1970-01-01
    • 2011-12-18
    • 1970-01-01
    相关资源
    最近更新 更多