7

我是否正确假设向 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 上测试了一些类似的代码,这似乎可以工作,但这并不意味着我不只是幸运,或者它不会因编译器而异。

4

3 回答 3

9

该标准在23.1.2/8有关关联容器中对此很清楚

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

于 2009-07-01T13:40:18.357 回答
4

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

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

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

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

于 2009-07-01T11:45:28.367 回答
0

是的,你可以指望这一点。

// 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";
于 2009-07-01T12:23:20.787 回答