Consider the following program. It creates a set of pointer-to-ints, and uses a custom indrect_less comparator that sorts the set by the value of the pointed-to integer. Once this is done, I then change the value of one of the pointed-to integers. Then, it can be seen the order of the set is no longer sorted (I suppose because the set doesn't know something got changed).
(Don't mind the C++0x loops, I'm running on VS2010)
#include <iostream>
#include <set>
using namespace std;
struct indirect_less {
bool operator()(int* l, int* r) const
{
return *l < *r;
}
};
int main()
{
set<int*, indirect_less> myset;
int* a = new int(5);
int* b = new int(6);
int* c = new int(7);
myset.insert(a);
myset.insert(b);
myset.insert(c);
cout << "Set contains: ";
// (outputs: 5 6 7)
for (auto i = myset.begin(), end = myset.end(); i != end; ++i)
{
cout << **i << " ";
}
cout << endl << "Modifying *a" << endl;
*a = 9; // point of interest
cout << "Set contains: ";
// (outputs: 9 6 7 - unsorted order)
for (auto i = myset.begin(), end = myset.end(); i != end; ++i)
{
cout << **i << " ";
}
cout << endl;
cin.get();
return 0;
}
1) Am I right that I am invoking undefined behavior? Is the entire state of myset
invalid after the line *a = 9;
?
2) Is the only correct way to do this to erase then re-insert a
?
3) Is there any way, once *a = 9;
has been run, to re-balance the set in to sorted order, with well-defined behavior?