[SOLVED] Sorting possible on a QVector that has a struct as elements



  • I have a QVector<marker>MarkerMap();

    marker is made up of:

    @
    typedef struct
    {
    int x;
    int y;
    quint16 intensity;
    }marker;
    @

    I would like to know if it's possible to sort the vector on the intensity member

    Thanks


  • Moderators

    Yes, either implement operator< for it or pass a lambda to qSort:
    @
    typedef struct
    {
    int x;
    int y;
    quint16 intensity;
    } marker;

    //Method 1:
    bool operator<(const marker& a, const marker& b) { return a.intensity < b.intensity; }
    //and then:
    QVector<marker> foo;
    foo << marker{1,1,10} << marker{1,1,5} << marker{1,1,23};
    qSort(foo);

    //Method 2:
    QVector<marker> foo;
    foo << marker{1,1,10} << marker{1,1,5} << marker{1,1,23};
    qSort(foo.begin(), foo.end(), [](const marker& a, const marker& b) { return a.intensity < b.intensity; });
    @



  • [quote author="Chris Kawa" date="1413309934"]Yes, either implement operator< for it or pass a lambda to qSort:
    @
    typedef struct
    {
    int x;
    int y;
    quint16 intensity;
    } marker;

    //Method 1:
    bool operator<(const marker& a, const marker& b) { return a.intensity < b.intensity; }
    //and then:
    QVector<marker> foo;
    foo << marker{1,1,10} << marker{1,1,5} << marker{1,1,23};
    qSort(foo);

    //Method 2:
    QVector<marker> foo;
    foo << marker{1,1,10} << marker{1,1,5} << marker{1,1,23};
    qSort(foo.begin(), foo.end(), [](const marker& a, const marker& b) { return a.intensity < b.intensity; });
    @[/quote]

    Thanks Chris for responding.

    I'm sorry I should have mentioned that qSort is now deprecated as of Qt 5.3 which is what I am using. Can I use the above with std:sort instead of qSort.


  • Moderators

    Sure, it works the same.



  • [quote author="Chris Kawa" date="1413313734"]Sure, it works the same.[/quote]

    Hmm. OK because both "methods" did not compile.

    Method 2 yields:

    error: C3867: 'QVector<marker>::begin': function call missing argument list; use '&QVector<marker>::begin' to create a pointer to member

    My call:

    @
    qSort(MarkerMap.begin, MarkerMap.end(), [](const marker& a, const marker& b) {return a.intensity < b.intensity;});
    @


  • Moderators

    Are you sure you didn't write begin instead of begin() ?

    Anyway I correct myself: sure, it works (almost) the same.
    std::sort always takes iterators not the whole container so in first method pass begin() and end() to it instead of just the container.



  • I left the parends out of the begin call. I'm trying it with qSort. Even though deprecated qSort still works (if used right that is).

    Method 1 for some reason still wouldn't compile


  • Moderators

    @
    #include <algorithm>
    #include <QVector>

    typedef struct
    {
    int x;
    int y;
    quint16 intensity;
    } marker;

    bool operator<(const marker& a, const marker& b) { return a.intensity < b.intensity; }

    int main()
    {
    QVector<marker> foo;
    foo << marker{1,1,10} << marker{1,1,5} << marker{1,1,23};
    std::sort(foo.begin(), foo.end());
    }
    @
    Works as expected.



  • Thanks, I need to see why this will not compile:

    @
    bool operator<(const marker& a, const marker& b) { return a.intensity < b.intensity; }
    @

    yields:

    C:\Users\Default.WIN-SHC18RVLNPH\Documents\Qt Projects\G14xx Dead Pixel Test\worker.cpp:31: error: C2601: 'operator <' : local function definitions are illegal
    worker.cpp(27): this line contains a '{' which has not yet been matched

    Update:

    I moved the operator to the top of the implementation file. The error stating the def was a local def tipped me off.

    Thanks


  • Moderators

    You need to start reading the error messages ;)
    It says that you can't declare operator< function inside another function. See my example. That operator needs to be at global scope.


Log in to reply