Reputation: 2248
here is the problem:
In my first class i have a vector, a double variable and I overload the comparison operators. Here is the relevant code:
class City
{
double distance;
std::vector<int> coordinates;
bool operator<(const City& city) const
{
return this->distance < city.distance;
}
// same for the greater-than operator but changing "<" to ">"
};
In another class I have a vector of cities, which I have to sort every time a condition is met. For that I have a struct defined as follows:
EDIT: (reference instead of value)
struct CitySortHelper {
bool operator() (const City &x, const City &y) const { return x < y; }
} city_sort;
Now the problem part, when I sort the vector new City objects appear, and I can't explain why:
EDIT:
// this prints all current objects in the vector
for (int i = 0; i < totalCities; i++) {
std::cout << cities->at(i) << std::endl;
}
// after the following line I get new City objects in the
// vector, that weren't there before the sort. The new objects
// always have distance = 0 and random values in the coordinates
std::sort(cities->begin(), cities->end(), city_sort);
// using the sort with no predicate also gives the same faulty results
std::sort(cities->begin(), cities->end());
EDIT: (the copy constructor and assignment operator)
City(const City &city)
{
this->distance = city.distance;
this->coordinates = city.coordinates;
}
City& operator= (const City &city)
{
this->distance = city.distance;
this->coordinates = city.coordinates;
return *this;
}
The weird part is that this only happens if I sort the City objects in ascending order, i.e. if I change the comparator operator in the CitySortHelper
from "<" to ">" everything works fine.
Any ideas why this happens ?? Any help is appreciated.
Upvotes: 3
Views: 2698
Reputation: 497
You shouldn't use std::sort()
if you want to preserve order, you should use std::stable_sort()
. stable_sort
guarantees elements maintain their relative order, sort
doesn't.
Also, it doesn't seem like sort
is your problem here. It seems there are City objects getting pushed into the vector somewhere, and you aren't noticing them because you're checking on a variable for size instead of the vector's iterators. Try printing like this instead and tell us what comes out:
for (std::vector <City> ::iterator it = cities->begin(); it != cities->end(); ++it) {
std::cout << *it << std::endl;
}
Upvotes: 1
Reputation: 726489
CitySortHelper
needs to take parameters by const reference, not by value. Another thing to keep in mind is that sort uses assignment operator for the City
; check that your assignment operator is working correctly. Taking care of these two issues should fix the problem.
Upvotes: 4
Reputation: 24403
Change your sort helper to have
bool operator() ( const City& x , const City& y) const
And also check that City copy constructor and assignment operator do the proper thing
Upvotes: 1