Как отсортировать массив struct / class на основе данных его членов? - PullRequest
2 голосов
/ 07 января 2020

Как отсортировать массив struct / class на основе данных его членов, когда это не удается?

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;                                          

struct O{
    const string n;
    int a=1;
};

bool bfunction (O a, O b) {
    return a.n < b.n; }

int main () {

    O m[]={ {"unta"}, {"jalan"}, {"sama"}, {"aki"} };


// using function in sort control
    sort (m.begin(), m.end(), &bfunction);
}

g cc дает:

 error: request for member ‘begin’ in ‘m’, which is of non-class type ‘O [4]’
     sort (m.begin(), m.end(), &bfunction);
             ^~~~~
 error: request for member ‘end’ in ‘m’, which is of non-class type ‘O [4]’
     sort (m.begin(), m.end(), &bfunction);
                        ^~~~~

искренняя полезная помощь оценили

Ответы [ 3 ]

3 голосов
/ 07 января 2020

Здесь допущены некоторые ошибки:

  1. sort (m.begin(), m.end(), &bfunction);, звонки begin() и end() на O[]. Но массив не имеет функций-членов вообще.

    У вас есть выбор: либо создайте m, std::array<O, 4> или std::vector<O>, либо используйте std::begin(m) и std::end(m), которые работают для массивов stati c.

  2. Функция сортировки должна принимать свои параметры через константную ссылку:

    bool bfunction (const O &a, const O &b)

  3. В функции сортировки a.n < b.n сравнивает два массива строк, но такое сравнение нигде не определено. Вот лог c ошибка вам нужно решить. Подумайте, что вы на самом деле хотите сравнить здесь. Сравнение определено для std::string, например, return a.n[0] < b.n[0]; будет работать.

  4. При сортировке чего-либо необходимо перемещать элементы. Но ваша структура O не имеет конструктора перемещения, потому что вы его не предоставите, и автоматически сгенерированный будет некорректно сформирован, потому что O имеет const членов.

    Я думаю, что лучший способ справиться с этим - сделать все переменные-члены частными и контролировать доступ к ним через методы получения и установки. На данный момент самый простой способ - просто удалить const.

3 голосов
/ 07 января 2020

Использование std::array

#include <iostream>
#include <algorithm>
#include <vector>
#include <array>    

struct O {
    std::string n;
    int a;

    O(const char* c) : a(1) { n = c; }
};

bool bfunction(O a, O b) {
    return a.n < b.n;
}

int main() {
    std::array<O, 4> m = { "unta", "jalan", "sama", "aki" };

    // using function in sort control
    std::sort(m.begin(), m.end(), &bfunction);
}
2 голосов
/ 07 января 2020

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

#include <iostream>
#include <algorithm>
#include <vector>
#include <array>

class O {
    std::string n;
    int a;

public: 

    O(const char* c, int a = 1) : n(c), a(a) {}

    const std::string& get_n() const { return n; }

};

bool bfunction(const O& a, const O& b) {
    return a.get_n() < b.get_n();
}

int main() {

    std::array<O, 4> m = { "unta", "jalan", "sama", "aki" };

    std::sort(m.begin(), m.end(), &bfunction);

    for(auto& x : m) { 
        std::cout << x.get_n() << ',';
    }
}

Живой код здесь .

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