Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

sorting a QList of QMaps



  • The following code snippet compiles fine (and works as expected) when compiling on Linux using g++

        QList<QMap<QString, QVariant>> steps;
        std::sort(steps.cbegin(), steps.cend(), [](QMap<QString, QVariant> step1, QMap<QString, QVariant> step2) -> bool
        {
            int ts1 = step1["ts"].toInt();
            int ts2 = step2["ts"].toInt();
            return ts1<ts2;
        });
    
    

    However, when I compile this for Android using clang, this fails with a number of errors starting with

    <snip>/Qt/Android/android-ndk-r19c/sources/cxx-stl/llvm-libc++/include/algorithm:3832:17: error: no matching function for call to 'swap'
                    swap(*__first, *__last);
                    ^~~~
    <snip>/Qt/Android/android-ndk-r19c/sources/cxx-stl/llvm-libc++/include/algorithm:4017:5: note: in instantiation of function template specialization 'std::__ndk1::__sort<(lambda at ../Apps/TradfriLuxMain.cpp:43:45) &, QList<QMap<QString, QVariant> >::const_iterator>' requested here
        __sort<_Comp_ref>(__first, __last, __comp);
        ^
    Main.cpp:43:10: note: in instantiation of function template specialization 'std::__ndk1::sort<QList<QMap<QString, QVariant> >::const_iterator, (lambda at Main.cpp:43:45)>' requested here
        std::sort(steps.cbegin(), steps.cend(), [](QMap<QString, QVariant> step1, QMap<QString, QVariant> step2) -> bool
             ^
    ...
    

    Any ideas what this rather cryptic error means and how to fix it?

    Thanks in advance,

    Marc


  • Qt Champions 2019

    I would pass step1 and step2 as const ref instead copying the data all the time.


  • Moderators

    @Marc_Van_Daele said in sorting a QList of QMaps:

    error: no matching function for call to 'swap'
                    swap(*__first, *__last);
                    ^~~~
    

    Behind the scenes, std::sort() calls std::swap() to move your elements around. However, std::swap() cannot be used with const iterators.

    std::sort(steps.cbegin(), steps.cend())
    

    To fix it, convert your const iterators to non-const iterators: std::sort(steps.begin(), steps.end())

    [](QMap<QString, QVariant> step1, QMap<QString, QVariant> step2) -> bool {...}
    

    This is valid code, but I agree with @Christian-Ehrlicher: Pass the parameters by const-reference, not by-value. This avoids making copies of your maps every time your lambda is called.



  • Thanks!
    Using begin()/end() indeed compiles fine!
    Thanks also for pointing out the (unintended) copy. I've switched to const-reference


Log in to reply