c++ - Why isn't my std::set sorted? -
i have class store data looks this:
class dataline { public: std::string name; boost::posix_time::time_duration time; double x, y, z; dataline(std::string _name, boost::posix_time::time_duration _time, double _x, double _y, double _z); //assign these, not going here bool operator < (dataline* dataline) { return time < dataline->time; } }
then read in bunch of data , .insert std::set of objects:
std::set<dataline*> data; data.insert( new dataline(newname, newtime, newx, newy, newz) ); //...insert data - out of order here
then run through data , stuff while appending new elements set.
boost::posix_time::time_duration machinetime(0,0,0); for(std::set<dataline*>::reverse_iterator = data.rbegin(); != data.rend(); ++it) { if(machinetime < (*it)->time) { machinetime = (*it)->time; } machinetime += processdataline(*it); //do stuff data, might add append list below for(std::vector<appendlist*>::iterator iter = appendlist.begin(); iter != appendlist.end(); ++iter) { data.insert( new dataline( (*iter)->name, machinetime, (*iter)->x, (*iter)->y, (*iter)->z); ); } }
when try loop through set of data both before , after inserting elements data out of order! here times outputted when looped using
for(std::set<dataline*>::iterator = data.begin(); != data.end(); ++it) { std::cout << std::endl << (*it)->time; } 14:39:55.003001 14:39:55.003002 14:39:55.001000 14:39:59.122000 14:39:58.697000 14:39:57.576000 14:39:56.980000
why aren't these times sorted in order?
it is sorted. it's sorted based on data type you're storing in set, pointer dataline
. in other words, it'll sort according location in memory of objects probably creation order (but may not be, depending on how memory allocation functions work in implementation).
if want sort based on dataline
type itself, don't use pointer. store objects themselves.
you can see similar effect following code creates 2 sets. first set of integer pointers, second set of actual integers:
#include <iostream> #include <iomanip> #include <set> using namespace std; int main (void) { set<int*> ipset; set<int> iset; cout << "inserting: "; (int = 0; < 10; i++) { int val = (i * 7) % 13; cout << ' ' << setw(2) << val; ipset.insert (new int (val)); iset.insert (val); } cout << '\n'; cout << "integer pointer set:"; (set<int*>::iterator = ipset.begin(); != ipset.end(); ++it) cout << ' ' << setw(2) << **it; cout << '\n'; cout << "integer set: "; (set<int>::iterator = iset.begin(); != iset.end(); ++it) cout << ' ' << setw(2) << *it; cout << '\n'; cout << "integer pointer set pointers:\n"; (set<int*>::iterator = ipset.begin(); != ipset.end(); ++it) cout << " " << *it << '\n'; cout << '\n'; return 0; }
when run code, see like:
inserting: 0 7 1 8 2 9 3 10 4 11 integer pointer set: 0 7 1 8 2 9 3 10 4 11 integer set: 0 1 2 3 4 7 8 9 10 11 integer pointer set pointers: 0x907c020 0x907c060 0x907c0a0 0x907c0e0 0x907c120 0x907c160 0x907c1a0 0x907c1e0 0x907c220 0x907c260
you can see unordered way in values added 2 sets (first line) , way pointer set in case matches order of input (second line). that's because addresses what's being used ordering can see fact final section shows ordered addresses.
although, mentioned, may not necessarily match input order, since memory arena may fragmented (as 1 example).
the set containing actual integers (as opposed pointers integers) sorted integer value (third line).
Comments
Post a Comment