Results 1 to 4 of 4

Thread: strange behavior of QMapIterator

  1. #1
    Join Date
    Nov 2007
    Posts
    55
    Thanks
    1
    Thanked 9 Times in 9 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default strange behavior of QMapIterator

    Hello community!

    I have following situation:

    Qt Code:
    1. typedef QMapIterator<double, QCPFinancialData> QCPFinancialDataMapIterator;
    2.  
    3. class QCP_LIB_DECL QCPFinancialData
    4. {
    5. public:
    6. QCPFinancialData();
    7. QCPFinancialData(double key, double open, double high, double low, double close);
    8. double key, open, high, low, close;
    9. friend QDebug operator<<(QDebug dbg, QCPFinancialData& data); // AW
    10. };
    To copy to clipboard, switch view to plain text mode 

    Here the code snippet:

    Qt Code:
    1. QCPFinancialDataMap map;
    2. QCPFinancialDataMapIterator it( map );
    3. // initialize map ...
    4. // map after initialization:
    5. map = QCPFinancialDataMap(QMap(0,QCPFinancialData(0,10,15,8,12) ) QMap(900,QCPFinancialData(900,11,16,7,13) ) QMap(1800,QCPFinancialData(1800,12,17,6,14) ) QMap(2700,QCPFinancialData(2700,13,18,5,15) ) )
    6. . . .
    To copy to clipboard, switch view to plain text mode 
    // I make 3 calls to it.next(), all behaving as expected.
    Then I have to go one step backwards, so I call it.previous(), but without any effect! I have to make a second call to it.previous() to get the desired result! Same behavior moving the iterator forward to reach the original position! - see code snippet and printout -

    Qt Code:
    1. qDebug() << "1: it.value().close =" << it.value().close; // OK, is 14
    2. it.previous(); // no effect!
    3. qDebug() << "2: it.value().close =" << it.value().close; // should be 13!
    4. it.previous(); // works as expected. Why is a double call of previous() necessary?
    5. qDebug() << "3: it.value().close =" << it.value().close; // OK, is 13
    6. currentBinData.close = it.value().close;
    7. it.next(); // no effect!
    8. qDebug() << "4: it.value().close =" << it.value().close; // should be 14!
    9. it.next(); // works as expected. Why is a double call of next() necessary?
    10. qDebug() << "5: it.value().close =" << it.value().close; // OK, is 14
    To copy to clipboard, switch view to plain text mode 

    print out:
    1: it.value().close = 14
    2: it.value().close = 14
    3: it.value().close = 13
    4: it.value().close = 13
    5: it.value().close = 14

    The code is doing what I want, but it is not clean.
    Any idea?

    Thank you for your time.
    Alain

  2. #2
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Thanks
    13
    Thanked 153 Times in 150 Posts
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: strange behavior of QMapIterator

    Hi, each next() or previous() moves the iterator after or before an item accordingly. The value() then returns the item that was skipped over by the next() or previous() methods, so the iterator is always moved past an item (for next) or moved before an item (for previous).

    The behavior of next() and previous() is undefined if you are past the end or before the beginning respectively. You don't really show where your iterator is sitting before you posted your example. My guess is that your iterator was pointing just past 14 (after a next call) when you ran the code shown in your post.

    Seems to me you should be moving your iterator with previous() and next() before you print the value() because the value() points to the item skipped over.

    Here's is what you posted for your example:

    Quote Originally Posted by alainstgt View Post
    Qt Code:
    1. qDebug() << "1: it.value().close =" << it.value().close; // OK, is 14
    2. it.previous(); // no effect!
    3. qDebug() << "2: it.value().close =" << it.value().close; // should be 13!
    4. it.previous(); // works as expected. Why is a double call of previous() necessary?
    5. qDebug() << "3: it.value().close =" << it.value().close; // OK, is 13
    6. currentBinData.close = it.value().close;
    7. it.next(); // no effect!
    8. qDebug() << "4: it.value().close =" << it.value().close; // should be 14!
    9. it.next(); // works as expected. Why is a double call of next() necessary?
    10. qDebug() << "5: it.value().close =" << it.value().close; // OK, is 14
    To copy to clipboard, switch view to plain text mode 
    Here's what I believe happens for each of your steps. The "I" below shows where the iterator is pointing for each step (again, I am assuming your have iterated past 14 using next() but not shown in your example):

    Qt Code:
    1. 12 13 14 I 15 // prints 14 because I am guessing you had iterated past 14 using next() prior to the example you posted
    2. 12 13 I 14 15 // after your call to previous()
    3. 12 13 I 14 15 // prints 14 because it was the most recent item skipped over (again)
    4. 12 I 13 14 15 // after your call to previous()
    5. 12 I 13 14 15 // prints 13 because it was most recent item skipped over
    6. 12 I 13 14 15 // this line of your code has no effect on the iterator, so no changes here
    7. 12 13 I 14 15 // after your call to next()
    8. 12 13 I 14 15 // prints 13 because it was the most recent item skipped over (again)
    9. 12 13 14 I 15 // after your call to next()
    10. 12 13 14 I 15 // prints 14 because it was the most recent item skipped over
    To copy to clipboard, switch view to plain text mode 

    The key is that the iterator never points exactly at an item, it points just before an item or just after an item, so when you switch directions, you traverse the same item twice.

    Hope that helps.
    Last edited by jefftee; 7th February 2015 at 05:58.

  3. #3
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,418
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: strange behavior of QMapIterator

    If you want an iterator that points to a respective entry instead of between entries, you can use STL-style ones.

    Qt Code:
    1. QCPFinancialDataMap::const_iterator it = map.constBegin();
    2. // it points to first entry
    3.  
    4. ++it;
    5. // it points to second entry
    6.  
    7. --it;
    8. // it points to first entry
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

  4. #4
    Join Date
    Nov 2007
    Posts
    55
    Thanks
    1
    Thanked 9 Times in 9 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: strange behavior of QMapIterator

    thank you to both!

    I was not aware that the the value() points to the item skipped over!
    You are right guessing that I had iterated past 14 , jthomps. Your description matches exactly my situation.

    Using a STL-like iterator is in that case more elegant.
    I used the Java-style iterator because it is defined as typedef in the library (qcustomplot) I am using.

    Alain

Similar Threads

  1. Qt process strange behavior
    By rspock in forum Newbie
    Replies: 5
    Last Post: 15th March 2013, 17:11
  2. Qt Creator Strange behavior of GDB in Creator 1.3
    By rayjc in forum Qt Tools
    Replies: 1
    Last Post: 11th March 2010, 21:42
  3. Strange behavior of QSqlTableModel
    By venomj in forum Qt Programming
    Replies: 0
    Last Post: 13th January 2010, 03:29
  4. Strange resize behavior
    By Lykurg in forum Newbie
    Replies: 3
    Last Post: 9th January 2007, 13:56
  5. scrollbars strange behavior
    By siniy in forum Qt Programming
    Replies: 6
    Last Post: 29th December 2006, 10:27

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.