Solved 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
-
I would pass step1 and step2 as const ref instead copying the data all the time.
-
@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!
Usingbegin()/end()
indeed compiles fine!
Thanks also for pointing out the (unintended) copy. I've switched to const-reference