Почему std :: sort () меняет отсортированный вектор? - PullRequest
3 голосов
/ 19 декабря 2011

вот проблема:

В моем первом классе у меня есть вектор, двойная переменная, и я перегружаю операторы сравнения.Вот соответствующий код:

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 ">"
};

В другом классе у меня есть вектор городов, который я должен сортировать каждый раз, когда выполняется условие.Для этого у меня есть структура, определенная следующим образом:

РЕДАКТИРОВАТЬ: (ссылка вместо значения)

struct CitySortHelper {
    bool operator() (const City &x, const City &y) const { return x < y; } 
} city_sort;

Теперь проблемная часть, когда я сортирую вектор, появляются новые объекты City, и яне могу объяснить, почему:

РЕДАКТИРОВАТЬ:

// 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());

РЕДАКТИРОВАТЬ: (конструктор копирования и оператор присваивания)

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;
}

Странная часть заключается в том, что это происходит толькоесли я сортирую объекты City в порядке возрастания, т. е. если я изменяю оператор сравнения в CitySortHelper с "<" на ">", то все работает нормально.

Есть идеи, почему это происходит ??Любая помощь приветствуется.

Ответы [ 3 ]

4 голосов
/ 19 декабря 2011

CitySortHelper должен принимать параметры по константной ссылке, а не по значению. Следует также помнить, что для сортировки используется оператор присваивания для City; проверьте, правильно ли работает ваш оператор присваивания. Забота об этих двух проблемах должна решить проблему.

1 голос
/ 02 января 2015

Не следует использовать std::sort(), если вы хотите сохранить заказ, вы должны использовать std::stable_sort(). stable_sort гарантирует, что элементы сохраняют свой относительный порядок, sort нет.

Кроме того, похоже, что sort не является вашей проблемой здесь. Кажется, что объекты City куда-то выталкиваются в вектор, и вы не замечаете их, потому что вы проверяете переменную размера вместо итераторов вектора. Попробуйте вместо этого напечатать и скажите нам, что получится:

for (std::vector <City> ::iterator it = cities->begin(); it != cities->end(); ++it) {
    std::cout << *it << std::endl;
}
1 голос
/ 19 декабря 2011

Измените ваш помощник сортировки, чтобы иметь

bool operator() ( const City& x , const City& y) const

А также проверьте, что конструктор копий и оператор присваивания делают все правильно

...