Qsort и несовместимая функция сравнения - С++

У меня есть структура subPolygon и вектор указателей на эту структуру. Я пытаюсь использовать qsort для вектора, но функция компаратора отображается как несовместимая. Что я делаю не так?

int cmpFunc(const void *p, const void *q) {
    struct subPolygon* p1 = *((struct subPolygon**)p);
    struct subPolygon* p2 = *((struct subPolygon**)q);
    int s1 = p1->size;
    int s2 = p2->size;
    if (s1-s2 < 0 ) return -1;
    if (s1 == s2) return 0;
    return 1;
}

Вот объявление вектора:

vector<subPolygon*> subPolygons;

Звонок qsort:

qsort(&subPolygons[0], subPolygons.size(), sizeof(struct subPolygon*),cmpFunc);

Изменить: похоже, проблема была в дополнительной ошибке: cmpFunc: non-standard synatx; use & to create pointer to a member " Моя функция сравнения была членом класса. Qsort был вызван из члена этого класса. Статическая функция моего компаратора решила проблему.


person John Katsantas    schedule 30.04.2018    source источник
comment
Почему вы пытаетесь использовать qsort в С++ для начала?   -  person Baum mit Augen    schedule 30.04.2018
comment
У меня есть курс по вычислительной геометрии, и мы не так много внимания уделяем изучению C++, поскольку нам нужны только базовые вещи. Мне просто нужна была сортировка, и я вспомнил функцию qsort из того, что я делал в своем курсе Java.   -  person John Katsantas    schedule 30.04.2018
comment
Я бы не стал рассматривать функции совместимости с устаревшими версиями, такие как qsort, как часть базовых вещей. И предположение о поведении C++ на основе опыта работы с Java имеет как минимум серьезные ограничения. Во всяком случае, нормальная функция сортировки в C++ — это std::sort, проверьте это.   -  person Baum mit Augen    schedule 30.04.2018
comment
Какая у вас ошибка? У меня это работает нормально...   -  person Max Langhof    schedule 30.04.2018
comment
@MaxLanghof Кажется, я получаю дополнительную ошибку cmpFunc: нестандартный синтаксис; использовать & для создания указателя на элемент   -  person John Katsantas    schedule 30.04.2018
comment
@JohnKatsantas: Это относится к вопросу, а не к комментариям под вопросом. Кроме того, продублируйте - ищите сообщение об ошибке в следующий раз. (Вот почему это относится к вопросу)   -  person MSalters    schedule 30.04.2018
comment
@MSalters До сих пор я не замечал этой ошибки. Я всегда ищу первым. Я уже потерял полчаса на поиски, прежде чем отправить сюда. Мне удалить вопрос?   -  person John Katsantas    schedule 30.04.2018
comment
Не обязательно; это просто еще один флаг в базе данных.   -  person MSalters    schedule 30.04.2018


Ответы (1)


Что вы действительно должны сделать:

bool compare(const subPolygon *p1, const subPolygon *p2)
{
    int s1 = p1->size;
    int s2 = p2->size;
    return (s1-s2 < 0);
    // Or just: return p1->size < p2->size;
}

std::sort(subPolygons.begin(), subPolygons.end(), compare);
person Max Langhof    schedule 30.04.2018
comment
ИМХО, что действительно должен делать ОП: std::sort(subPolygons.begin(), subPolygons.end(), [](const subPolygon* p1, const subPolygon* p2) { return p1->size < p2->size; }); - person Borgleader; 30.04.2018
comment
Я думал об этом, но не хотел бросать лямбда-выражения новичку в C++. Но да, лямбда-решение, как правило, лучше (если у вас нет большого количества вызовов сортировки, тогда повторение лямбда начнет пахнуть). - person Max Langhof; 30.04.2018
comment
@MaxLanghof Спасибо за понимание. Я пробовал это, и я все еще получаю это использование & для создания указателя на ошибку члена. - person John Katsantas; 30.04.2018
comment
Затем приведите более полный пример, потому что это работает для меня. - person Max Langhof; 30.04.2018
comment
@JohnKatsantas compare не должен быть членом какого-либо класса - person Caleth; 30.04.2018
comment
@Caleth: Нет ничего плохого в члене static. Проблема в том, что compare в реализованном виде будет принимать три аргумента: его нужно будет вызывать как a.compare(b,c). qsort ожидает что-то, что может называться compare(a,b), а &subPolygon::compare может соответствовать. - person MSalters; 30.04.2018
comment
Это действительно член класса в моем коде. Однако структура является членом этого класса, и функция сравнения не распознает ее, пока я не сделаю ее членом класса. Извините за беспокойство, я могу работать здесь. - person John Katsantas; 30.04.2018
comment
(s1-s2 < 0) это кажется бессмысленным и потенциально опасным, если s2 отрицательное (поскольку это может привести к UB в форме переполнения). Почему бы просто не сделать s1 < s2? - person Yakk - Adam Nevraumont; 30.04.2018
comment
@Yakk Потому что я хотел, чтобы код был достаточно похож на OP. В его коде есть гораздо более насущные проблемы, чем беспокойство о переполнении. И да, s1 < s2 обычно более понятен, чем вычитание, но этот промежуточный шаг делает эквивалентность двух очевидными, поэтому я подумал, что он оптимален для этой цели (поскольку вопрос в любом случае дублируется). - person Max Langhof; 30.04.2018