Как отсортировать массив объектов независимо от типа переменной объекта - PullRequest
0 голосов
/ 01 июня 2019

У меня есть массив объектов Record, и у каждого объекта записи есть 5 полей (имя, фамилия, GPA, идентификационный номер и адрес электронной почты). Я хочу отсортировать массив на основе любой из переменных, приписываемых объекту. Мой профессор говорит, что есть способ использовать одну функцию, которая будет сортировать ее независимо от типа передаваемой переменной. Но я не могу найти способ иметь одну функцию, которая может сортировать любую из этих 5 переменных и 3 различных типов переменных. Это означает, что я не могу просто скопировать и вставить функцию сортировки 5 раз для каждой переменной. Пока что я могу отсортировать массив по одному значению, например, record []. GPA, но мне нужен способ, подобный record []. X, где x - это любая переменная, по которой пользователь решит, какой массив мы должны отсортировать.

Я попытался создать функцию сортировки, и она сортируется нормально, но она может обрабатывать только одну переменную одновременно. Например, мне нужно написать record [i] .GPA, чтобы он сравнивал GPA двух записей. Однако мой учитель хочет, чтобы функция могла сортировать по любому из полей.

template <class  T>
void sortArray(T record[]) {

    bool swap = true;
    while (swap) {
        swap = false;
        for (size_t i = 0; i < arraySize - 1; i++) {
            if (record[i].GPA< record[i + 1].GPA) {
                T temp = record[i];
                record[i] = record[i + 1];
                record[i + 1] = temp;
                swap = true;
            }
        }
    }
}

Это мой код сортировки, как вы можете видеть, я должен был указать, какую переменную записи сортировать, в данном случае GPA, но мне нужно, чтобы она сортировалась по любой из переменных записи в зависимости от выбора пользователя. Я не предполагаю иметь несколько функций сортировки для каждой переменной. Я могу опубликовать остальную часть своего кода, если требуется.

1 Ответ

3 голосов
/ 01 июня 2019

Вы можете сделать что-то вроде:

auto makeComp = [](auto member){
    return [=](const auto& lhs, const auto& rhs){
        return std::invoke(member, lhs) < std::invoke(member, lhs);
    }
};

switch (eMember)
{
    case EMember::FirstName: std::sort(record, record + arraySize, makeComp(T::FirstName)); break;
    case EMember::LastName:  std::sort(record, record + arraySize, makeComp(T::LastName)); break;
    case EMember::GPA:       std::sort(record, record + arraySize, makeComp(T::GPA)); break;
    case EMember::Id:        std::sort(record, record + arraySize, makeComp(T::Id)); break;
    case EMember::EMail:     std::sort(record, record + arraySize, makeComp(T::Email)); break;
}
...