iska
iska

Reputation: 2248

Why does std::sort() change the sorted vector?

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

Answers (3)

Brian Rodriguez
Brian Rodriguez

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

Sergey Kalinichenko
Sergey Kalinichenko

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

parapura rajkumar
parapura rajkumar

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

Related Questions