I'm having problems with unique().

I have some code that goes something like this:

std::map<int, CompCont> sysRelMap;

for each(pair<int, CompCont> comp in sysRelMap)
{
	list<pair<string,string>>::iterator newEnd = 
		unique(comp.second.connList.begin(), comp.second.connList.end(), equalPair);
	comp.second.connList.erase(newEnd,comp.second.connList.end());
}

equalPair is a small, simple function:

bool ScriptWriter::equalPair(const pair<string, string> first, const pair<string, string> second)
{ 
	return (first.first.compare(second.first) == 0) && (first.second.compare(second.second) == 0);
}

CompCont is a class I created that contains, for this example, one important data member, a list< pair<string,string> > connList. When I set a breakpoint at the end of each for loop, it lists comp.second.connList correctly (with only unique pairs) but as soon as it breaks out of that for loop sysRelMap goes back to having the values of each CompCont.connList to what it was before unique() and erase() were called. Hopefully this is understandable.

I'm assuming it's somehow that my functions are being passed copies of the list objects instead of references to them, but am not sure how I would modify my code to handle. I just followed many of the examples online for how to do this with the Binary Predicate function, and they all looked similar to what I have. I didn't see anything about passing references, etc, but they also weren't dealing with lists encapsulated in other objects.

I thought this might work:

for each(pair<int, CompCont> comp in sysRelMap)
{
	list<pair<string,string>> modList = comp.second.connList;
	list<pair<string,string>>::iterator newEnd = 
		unique(modList.begin(), modList.end(), equalPair);
	modList.erase(newEnd,modList.end());
	comp.second.connList = modList;
}

.. but it didn't. Still, afterwards, the list objects in each CompCont in the sysRelMap remain the same as they were before the for each loop.

Any input would be greatly appreciated. Feel like I'm missing something small, and that's bugging me.

The "for each" statement isn't part of standard C++, so I'm not familiar with its exact semantics. However, I would expect that it would have to work by making comp a copy of each element in turn of sysRelMap .

The reason is simple: If it didn't make a copy, what would happen if you changed the value of comp.first ? Presumably that would change the key of the corresponding element of the map. Would that then somehow cause the map to be reordered? By what magic would the map detect that the element had changed?

For such reasons, using an iterator to access the elements of such a map would give you elements of type pair<const int, CompCont> . The fact that your "for each" doesn't do so suggests strongly that the elements are being copied.

This article has been dead for over six months. Start a new discussion instead.