Question

Am I right in assuming that adding/removing elements to an std::map does not effect the other elements (ie cause them to be relocated in memory) and so that the following is safe:

I looked at various sites with info on the container but only found out about the cases where iterators are invalidated, which I already know...

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"

I tested some similar code on VC9, which seems to work however that doesn't mean I didn't just get lucky or that it doesn't vary across compilers.

Was it helpful?

Solution

The Standard is clear on this in 23.1.2/8 about associative containers

The insert members shall not affect the validity of iterators and references to the container, and the erase members shall invalidate only iterators and references to the erased elements.

OTHER TIPS

Map has the important property that inserting a new element into a map does not invalidate iterators that point to existing elements. quote taken from sgi docs.

If the iterators are guaranteed not to change then the values they point at also cannot change.

naveen previously had an answer that was similar to this. Unless there is a mistake in my logic what you are doing is safe.

Edit 2: See point 3 in sgi docs to see how getting a value from operator [] is the same as getting the value from an iterator.

Yes you can count on this.

// 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";
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top