C ++: Как отсортировать вектор объектов, производных от класса, используя один из его параметров - PullRequest
0 голосов
/ 05 апреля 2019

Я пытаюсь отсортировать вектор объектов, созданный из класса в проекте.

У меня есть два класса - Playlist и ListIndex, который наследуется от класса List_base.В классе List_base я хочу отсортировать вектор объектов (Playlist или ListIndex) по их имени.свойство name определяется в классе List_base.Я попытался использовать структуру или функцию, которая сравнивает поле имени и передает его в функцию сортировки.Я получаю все виды ошибок.Я новичок в C ++ и застрял в этой ошибке очень долго

Метод сортировки List_base с функцией сравнения

//the function should be able to get either Playlist vector
// or ListIndex vector (both inherits from List_base)
void List_base::sortList(vector<List_base> data) {
    sort(data.begin(), data.end(), compFunc());
}

bool List_base::compFunc(List_base *a, List_base *b) {
    return a->getName().compare(b->getName()) > 0;
}

Поле имени объявлено в классе List_base:

class List_base
{
    public:
        List_base(string name);
        string getName();
        void sortList(vector<List_base> data);
        virtual ~List_base();

    protected:

    private:
        string name;
        bool compFunc(List_base *a, List_base *b);
};

Что я делаю не так?Я даже не могу сосредоточиться на конкретной ошибке.Я также пробовал кастовать, но там тоже не получилось

Пожалуйста, помогите!

1 Ответ

1 голос
/ 05 апреля 2019

std::sort ожидает, что передаваемый вами компаратор будет некоторого вызываемого типа, будь то указатель функции, функтор, лямбда и т. Д. Ему просто нужно что-то, что можно вызвать с сигнатурой, такой как bool compare(const T& left, const T& right).

Первая проблема заключается в том, что передача compFunc() - это , вызывающая функцию compFunc.Это должно завершиться сбоем, поскольку compFunc ожидает два аргумента.Вы должны передать саму функцию, а не ее возвращаемое значение:

sort(data.begin(), data.end(), compFunc);

Вторая проблема заключается в том, что в вашей функции сравнения вы должны принимать аргументы по ссылке на const, а не по указателю:

bool compFunc(const List_base& a, const List_base& b);

где List_base - это именно тот тип элемента, который вы сортируете.

Третья проблема заключается в том, что compFunc является нестатической функцией-членом .Это означает, что эта функция зависит от List_base экземпляра , который будет использоваться, и вам необходим секретный параметр this для его вызова, как в this->compFunc(...).Вместо этого вы должны сделать его static или не являющимся членом, чтобы его можно было рассматривать как обычную функцию.

class List_base {
    /* ... */
    static bool compFunc(const List_base& a, const List_base& b);
};

bool List_base::compFunc(const List_base& a, const List_base& b){
    return a.name < b.name;
}

На этом этапе ваша сортировка должна работать.Если вы хотите использовать отсортированный результат за пределами List_base::sortList, вы должны принять data по reference , чтобы внесенные изменения были видны вызывающей стороне.В настоящее время sortList принимает список по значению, что означает, что он всегда получает копию того, что вы передаете ему.

Возможно, самым чистым решением для всего этого будет оператор «меньше» (<), который стандартная библиотека использует по умолчанию во многих случаях для сравнения пользовательских типов.Это может выглядеть примерно так:

class List_base {
    /* ... */
    friend bool operator<(const List_base& a, const List_base& b){
        return a.name < b.name;
    }
};

, вам не нужно явно указывать свой собственный компаратор, а сортировка теперь так же проста, как

sort(data.begin(), data.end());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...