11.2.  Generics, Algorithms, and Operators

[ fromfile: generics.xml id: genericoperators ]

Overloading operator symbols makes it possible to define a common interface for our classes that is consistent with that of the basic types. Many generic algorithms take advantage of this by using the common operators to perform basic functions such as comparison.

qSort

The qSort() function is a generic algorithm implemented using the heapsort algorithm.[84] Example 11.6, shows how it can be used on two similar but different containers.

qSort() can be applied to any Qt container of objects that have publicly defined functions operator<() and operator==(). Containers of primitive numeric types can also be sorted with this function.

Example 11.6. src/containers/sortlist/sortlist4.cpp

#include <QList>
#include <QtAlgorithms>   // for qSort()
#include <QStringList>
#include <QDebug>

class CaseIgnoreString : public QString {
public:
    CaseIgnoreString(const QString& other = QString()) 
    : QString(other) {}
    bool operator<(const QString & other) const {
        return toLower() < other.toLower();
    }
    bool operator==(const QString& other) const {
        return toLower() == other.toLower();
    }
};

int main() {
    CaseIgnoreString s1("Apple"), s2("bear"),
                     s3 ("CaT"), s4("dog"), s5 ("Dog");

    Q_ASSERT(s4 == s5);
    Q_ASSERT(s2 < s3);
    Q_ASSERT(s3 < s4);

    QList<CaseIgnoreString> namelist;

    namelist << s5 << s1 << s3 << s4 << s2; 1

    qSort(namelist.begin(), namelist.end());
    int i=0;
    foreach (const QString &stritr, namelist) {
        qDebug() << QString("namelist[%1] = %2")
                       .arg(i++).arg(stritr) ;
    }

    QStringList strlist;
    strlist << s5 << s1 << s3 << s4 << s2; 2

    qSort(strlist.begin(), strlist.end());
    qDebug() << "StringList sorted: " + strlist.join(", ");
    return 0;
}

1

Insert all items in an order that is definitely not sorted.

2

The value collection holds QString but, if you add CaseIgnoreString, a conversion is required.

<include src="src/containers/sortlist/sortlist4.cpp" href="src/containers/sortlist/sortlist4.cpp" id="caseignorestring" mode="cpp"/>


operator<<(), which is the left shift operator from C, has been overloaded in the QList class to append items to the list.

Example 11.7 shows the output of this program.

Example 11.7. src/containers/sortlist/sortlist-output.txt

namelist[0] = Apple
namelist[1] = bear
namelist[2] = CaT
namelist[3] = dog
namelist[4] = Dog
StringList sorted: Apple, CaT, Dog, bear, dog

<include src="src/containers/sortlist/sortlist-output.txt" href="src/containers/sortlist/sortlist-output.txt" id="sortlistoutputtxt" mode="text"/>


Notice that CaseIgnoreString objects get case sensitive sorting when they are added to a QStringList. This is because each CaseIgnoreString must be converted into a QString as it is added to strlist. Therefore, when strlist's elements are compared, they are compared as QStrings and sorted with case sensitivity.



[84] There is a nice article about heapsort in Wikipedia