Home > Enterprise >  Problem on std::sort with QObject and QVector<MyQObject*>
Problem on std::sort with QObject and QVector<MyQObject*>

Time:04-04

I have a problem with sort of QVector<MyQObject*>. This is in real case of use for listing directorys and datas (like ls unix command). Here in this example "/Users/Stephane/" on my unix mac os computer.

The std::sort function doesn't work, I'm sure I have done a mistake.

Here are my files of Console Qt:

entry.h

#ifndef ENTRY_H
#define ENTRY_H

#include <QObject>
#include <QString>
#include <QDateTime>

enum Type {
    File, Directory, Other
};


class Entry : public QObject
{
Q_OBJECT
public:
    explicit Entry(QObject *parent = nullptr);
    void setValue(Type type, QString name, int size_file);
    QString getName();
    int getSize();
    bool operator<(const Entry other);
signals:
private:
    QString name;
    Type type;
    int size_file;
};

#endif // ENTRY_H

entry.cpp

#include "entry.h"

Entry::Entry(QObject *parent)
        : QObject{parent}
{

}

void Entry::setValue(Type type, QString name, int size_file)
{
    this->type = type;
    this->name = name;
    this->size_file = size_file;
}

QString Entry::getName()
{
    return this->name;
}

int Entry::getSize() {
    return this->size_file;
}

bool Entry::operator<(const Entry other) {
    return this->name < other.name;
}

main.cpp

#include <QCoreApplication>
#include "entry.h"
#include <sys/stat.h>
#include <dirent.h>
#include <QDebug>
#include <iostream>
#include <QDateTime>

struct EntryCompare {
    bool operator()(const Entry *a, const Entry *b) {
        return(a < b);
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // My vector
    QVector<Entry*> vec_entry;
    QString directory = "/Users/Stephane/";

    // Read dir/file
    struct dirent *lecture;
    DIR *dir;
    struct stat buf;
    QString currentPath;

    dir = opendir(directory.toLocal8Bit());
    if (dir == NULL) {
        qCritical() << directory << " don't exist";
        return a.exec();
    }

    while ((lecture = readdir(dir)) != NULL) {
        if (strcmp(lecture->d_name, ".") != 0) {
            currentPath = directory   lecture->d_name;
            const char *charCurrentPath = currentPath.toLocal8Bit();
            if ((stat(charCurrentPath, &buf)) == -1) {
                qCritical() << "stat" << currentPath;
            }
            int size = buf.st_size;
            Entry *entry = new Entry();
            if (!strcmp(lecture->d_name, "..")) {
                entry->setValue(Type::Directory, lecture->d_name, 0);
                vec_entry.append(entry);
            } else {
                vec_entry.append(entry);
                if (S_ISDIR(buf.st_mode)) {
                    QString qstringTemp = lecture->d_name;
                    qstringTemp  = "/";
                    entry->setValue(Type::Directory, qstringTemp, 0);
                } else {
                    entry->setValue(Type::File, lecture->d_name, size);
                }
            }
        }
    }
    closedir(dir);

    // This part doesn't work
    std::sort(vec_entry.begin(), vec_entry.end(), EntryCompare());

    foreach(Entry *v, vec_entry) {
        qInfo() << "Vector entry:" << v << "Name:" << v->getName() << "Size:" << v->getSize();
    }

    return a.exec();
}

CodePudding user response:

When you pass a pointer to any function, it's your responsibility to dereference the pointer and get from it the information it points to. That is not automatic -- you have to write the code to do it.

As to std::sort "not working", it is working exactly as you've written. Your comparison spec is comparing the value of two pointers. You're responsible for providing std::sort

  1. The proper range to sort, plus
  2. The proper sorting criteria that sorts two values, plus
  3. The sorting criteria follows a "strict-weak-ordering" (no ambiguities as to which item is placed before another item).

If you do that, std::sort works all the time. If the results are wrong, you must have violated one or more of those prerequisites. Your code violates number 2).

In all likelihood, you meant to do the following:

struct EntryCompare 
{
    bool operator()(Entry *a, Entry *b) const
    {
        return(a->getName() < b->getName());
    }
};

This compares the names that a and b point to.

  • Related