Tuesday, December 22, 2015

Reverse Iterators in Qt 5.6

Reverse iterators are among new features of Qt 5.6 release (Qt 5.6 beta was released last week). Now they are supported for all Qt sequential containers (QList, QLinkedList, QVector, QStack and QQueue).

If we look at C++ standard library and its sequence containers (array, vector, list, forward_list, deque) we will notice that these containers support both iterators (begin, end) and reverse iterators (rbegin, rend). Well, ok, except forward_list, special alternative to list when reverse iteration not needed.

Now we will solve a simple task like iterating a QList backwards with a new means available (similar to this http://stackoverflow.com/questions/16441447/iterating-over-a-qlist-backwards):
#include <QCoreApplication>
#include <iostream>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QList<int> list = {1, 2, 3, 4};
    QList<int>::const_reverse_iterator cIter;
    cIter = list.crbegin();
    while(cIter != list.crend()) {
      std::cout << *cIter << std::endl;
      ++cIter;
    }
    return a.exec();
}

Output from this program is: 4 3 2 1

QList::crbegin() points to the first item in the list in the reverse order. It returns const_reverse_iterator.

QList::crend() points to the last item in the list in the reverse order. It also returns const_reverse_iterator.

reverse_iterators and const_reverse_iterators are working well with auto C++11 keyword. Here is the example:

#include <QCoreApplication>
#include <QVector>
#include <iostream>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QVector<int> qVector = {1, 2, 3, 4, 5};
    for (auto it = qVector.rbegin(); it != qVector.rend(); ++it)
    {
        std::cout << *it << std::endl;
    }
    return a.exec();
}
As you may guess, the output from this simple program is: 5 4 3 2 1