Передача функции сравнения в qsort c ++

0

Моя функция сравнения зависит от членов данных в Foo, и поэтому я хочу содержать ее в этом классе. Все примеры используют глобальные функции, которые работают, но не то, что я ищу. Я хотел бы, чтобы каждый экземпляр Foo имел другое сравнение, основанное на текущем статусе объекта.

class Foo
{
public:
   Foo(){}

   int Compare(const void * a,const void * b)
   {
    //Comparing logic
    //This is fine
   }

   void SortStuff(void)
   {
    qsort(ObjectArray,MAXOBJECTS,sizeof(Object*), Compare);
   }    

};
  • 13
    Сделайте себе одолжение и используйте std::sort . Это делает такие вещи тривиальными.
  • 0
    Это даже не должно компилироваться. qsort не может принять указатель на нестатическую функцию-член.
Показать ещё 3 комментария
Теги:
sorting

1 ответ

1

Как упоминалось в комментарии @juanchopanza, настоятельно рекомендуется использовать std::sort over qsort в C++. Алгоритм std::sort корректно вызывает операции присваивания и безопасен по типу, а qsort - нет. Например, если вы попытаетесь использовать qsort для сортировки массива std::string s, вы получите неопределенное поведение.

Тем не менее, если вы абсолютно должны использовать qsort таким образом, проблема, с которой вы сталкиваетесь, - это "невидимый this " указатель. В C++ функции-члены принципиально отличаются от бесплатных функций, потому что для вызова функции-члена вам необходимо предоставить объект-получатель. В коде, который вы написали выше, вы получаете сообщение об ошибке, потому что qsort ожидает бесплатную функцию, которая может быть вызвана двумя аргументами, но вы предоставили ей функцию-член, которая хочет два аргумента, для которых действительно действительно нужны три аргумента - объект приемника и два указателя.

Чтобы исправить это, у вас есть несколько вариантов. Один из вариантов заключается в том, чтобы пометить функцию static, указав, что это свободная функция, ограниченная внутри вашего класса, а не функция-член. Другим вариантом было бы использовать lambdas для определения функции сравнения, поскольку C++ lambdas без списков захвата являются свободными функциями. Я бы рекомендовал второй вариант по сравнению с первым, если вам не нужна функция сравнения в нескольких местах, поскольку она более четко указывает, что вам просто нужна функция как одноразовая.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню