[Qt-interest] Problem with qSort and QObjects

Florian VICHOT florian.vichot at diateam.net
Sun Feb 14 16:13:25 CET 2010


Hey Carl,

Actually, the fix is simple, and it is something you will have to do for
every object you derive from QObject: add a copy constructor that calls
QObject() instead of QObject(const QObject & o) as the QObject copy
constructor is private.

So just add :

Account(const Account & a) : QObject() {};

And you're golden :)

As stated in the documentation, qSort needs nothing more than a
operator<() defined.

Florian


Le 14/02/10 01:19, Carl Snellman a écrit :
> Hey all,
> 
> I've been fighting to get qSort working with following code: (adopted
> from http://lists.trolltech.com/qt-interest/2008-07/thread00695-0.html)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
> #include <QtCore/QCoreApplication>
> #include <iostream>
> #include <QtAlgorithms>
> #include <QDebug>
> #include <QObject>
> 
> class Account : QObject {
> public:
>     Account() {};
>     Account(QString aItem, QString bItem)
>              : aItem(aItem), bItem(bItem) {};
>     QString aItem;
>     QString bItem;
>     QString toString(){
>         QString result;
>         return result.append("aItem = ").append(aItem).append("\t")
>                 .append("bItem = ").append(bItem).append("\n");
>     };
>     bool operator<(const Account & other ) const {
>         qDebug() << "Comparing: " << aItem << ":" << other.aItem;
>         return aItem < other.aItem;
>     };
> };
> 
> int main(int argc, char *argv[]) {
>     QCoreApplication a(argc, argv);
>     QList<Account> list;
>     list << Account("item 5", "Dummy");
>     list << Account("item 1", "Dummy");
>     list << Account("item 3", "Dummy");
>     list << Account("item 4", "Dummy");
>     list << Account("item 2", "Dummy");
> 
>     for (int i=0; i<5; ++i)
>         std::cout << list.value(i).toString().toStdString();
>     std::cout << "==================\n";
> 
>     qSort(list);
> 
>     for (int i=0; i<5; ++i)
>         std::cout << list.value(i).toString().toStdString();
>     return 0;
> }
> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
> 
> Above gives me the following compilation errors:
> 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
> Running build steps for project qSortAccountTest...
> Configuration unchanged, skipping QMake step.
> Starting: /usr/bin/make -w
> make: Entering directory
> `/scratchbox/users/maemo/home/maemo/qSortAccountTest/qSortAccountTest'
> g++ -c -pipe -g -Wall -W -D_REENTRANT -DQT_CORE_LIB -DQT_SHARED
> -I/home/maemo/qtsdk-2010.01/qt/mkspecs/linux-g++ -I.
> -I/home/maemo/qtsdk-2010.01/qt/include/QtCore
> -I/home/maemo/qtsdk-2010.01/qt/include -I. -o main.o main.cpp
> /home/maemo/qtsdk-2010.01/qt/include/QtCore/qobject.h: In copy
> constructor 'Account::Account(const Account&)':
> main.cpp:7: instantiated from 'T QList<T>::value(int) const [with T = Account]'
> main.cpp:35: instantiated from here
> /home/maemo/qtsdk-2010.01/qt/include/QtCore/qobject.h:309: error:
> 'QObject::QObject(const QObject&)' is private
> main.cpp:7: error: within this context
> /home/maemo/qtsdk-2010.01/qt/include/QtCore/qlist.h: In member
> function 'T QList<T>::value(int) const [with T = Account]':
> /home/maemo/qtsdk-2010.01/qt/include/QtCore/qlist.h:589: note:
> synthesized method 'Account::Account(const Account&)' first required
> here
> /home/maemo/qtsdk-2010.01/qt/include/QtCore/qobject.h: In member
> function 'Account& Account::operator=(const Account&)':
> main.cpp:7: instantiated from 'void
> QList<T>::node_construct(QList<T>::Node*, const T&) [with T =
> Account]'
> /home/maemo/qtsdk-2010.01/qt/include/QtCore/qlist.h:472: instantiated
> from 'void QList<T>::append(const T&) [with T = Account]'
> /home/maemo/qtsdk-2010.01/qt/include/QtCore/qlist.h:315: instantiated
> from 'QList<T>& QList<T>::operator<<(const T&) [with T = Account]'
> main.cpp:28: instantiated from here
> /home/maemo/qtsdk-2010.01/qt/include/QtCore/qobject.h:309: error:
> 'QObject& QObject::operator=(const QObject&)' is private
> main.cpp:7: error: within this context
> /home/maemo/qtsdk-2010.01/qt/include/QtCore/qlist.h: In member
> function 'void QList<T>::node_construct(QList<T>::Node*, const T&)
> [with T = Account]':
> /home/maemo/qtsdk-2010.01/qt/include/QtCore/qlist.h:353: note:
> synthesized method 'Account& Account::operator=(const Account&)' first
> required here
> make: Leaving directory
> `/scratchbox/users/maemo/home/maemo/qSortAccountTest/qSortAccountTest'
> make: *** [main.o] Error 1
> Exited with code 2.
> Error while building project qSortAccountTest
> When executing build step 'Make'
> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
> 
> Now, if I change the Account class not to extend QObject, everything
> works fine, and output is sorted.
> So I would have two questions:
> 1) What I need to do to get the QObject version working? qSort docs
> say that the items need to implement operator<(), but clearly that is
> not enough.
> 
> 2) Is it possible to overload the operator<() this way (using
> pointers) and use it with qSort?
>     bool operator<(const Account * other ) const;
> My app actually stores pointers to objects (extending QObject) in the
> QList that I want to sort, so will it be possible at all?
> 
> Any help is greatly appreciated!
> Thanks,
> Carl
> _______________________________________________
> Qt-interest mailing list
> Qt-interest at trolltech.com
> http://lists.trolltech.com/mailman/listinfo/qt-interest




More information about the Qt-interest-old mailing list