4

I have created a simple map and an iterator on it. When i move the iterator to next items, it performs well. After forwarding the iterator, if I ask it to go back for previous item and get value() of the iterator, it is not really the previous item value and actually the value is not changed at all. It seems there is something wrong or maybe I'm using it in a wrong way! Where is the problem?

see the below code

#include "mainwindow.h"
#include <QApplication>
#include <QMap>
#include <qiterator.h>

int main(int argc, char *argv[])

{
    QApplication a(argc, argv);

QMap<double,int> map;
map.insert(4234,3);
map.insert(4200,2);
map.insert(4100,1);
map.insert(4000,0);

QMapIterator<double, int> i(map);
i.toFront();

i.next();
i.next();
int va1 = i.value();    // val1 is 1 as expected

i.previous();

int val2 = i.value(); // It is expected that val2 should be 0 but is still Surprisingly 1!!!!

return a.exec();
}
Mosi
  • 1,178
  • 2
  • 12
  • 30
  • what do you get if you loop over the iterator and print the value? I'd guess that you'd get 0,1,2,3 (as that's the order of your keys, not values) ... which means when you do next() next() previous() - you'd be getting the 2nd value - a 1 NOTE: I'm asking because I don't have QT installed – UKMonkey Oct 18 '16 at 13:19
  • Yes because of the keys order it would be : 0,1,2,3. By first next() the value is 0 and by the second next() the value is 1 so by calling a previous(), I expect the iterator to point to the first item but the i.value() returns still second item! – Mosi Oct 18 '16 at 13:24
  • So the issue is why your first test, after front(), next() next() value() is a 1 rather than a 2. – UKMonkey Oct 18 '16 at 13:26
  • No, the issue is why after front(), next() next() previous(), value() is 1 rather than 0! – Mosi Oct 18 '16 at 13:26
  • well - because the front is 0, and a next(), next(), previous() can be shrunk to "next()" - which is 1. – UKMonkey Oct 18 '16 at 13:27
  • I removed the front() and I still have same results!!! – Mosi Oct 18 '16 at 13:30

1 Answers1

1

This is by design and a behavior of the Java-style iterators. The iterators have two important pieces of state associated with them:

  1. Position.
  2. Direction.

In all cases, the iterator points to the item it most recently stepped over.

Using next() and previous() reverses the iterator's direction. After next(), the iterator steps right and points to the item to its left. After previous(), the iterator steps left and points to the item to its right.

Here's the annotated execution order. The - flag indicates the pointed-to value based on iterator's direction. The v symbol indicates the iterator position.

i.toFront();
-v
  4000 4100 4200 4234
  0    1    2    3

i.next();
  ----v
  4000 4100 4200 4234
  0    1    2    3

i.next();
       ----v
  4000 4100 4200 4234
  0    1    2    3

i.previous();
      v----
  4000 4100 4200 4234
  0    1    2    3

i.previous();
 v----
  4000 4100 4200 4234
  0    1    2    3

Test case:

#include <QtCore>
int main()
{
   QMap<double, int> map;
   map.insert(4234., 3);
   map.insert(4200., 2);
   map.insert(4100., 1);
   map.insert(4000., 0);

   QMapIterator<double, int> i(map);
   i.toFront();

   i.next();
   qDebug() << i.key() << i.value();
   i.next();
   qDebug() << i.key() << i.value();

   i.previous();
   qDebug() << i.key() << i.value();
   i.previous();
   qDebug() << i.key() << i.value();
}

Output:

4000 0
4100 1
4100 1
4000 0

If you didn't expect that behavior, perhaps C++-style iterators would be easier to apply.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313