Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Erasing QHash while iterating the hash table?
QtWS25 Last Chance

Erasing QHash while iterating the hash table?

Scheduled Pinned Locked Moved Solved General and Desktop
qhasherase
7 Posts 3 Posters 3.5k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    bigapple
    wrote on 11 Jan 2016, 22:45 last edited by bigapple 1 Dec 2016, 17:36
    #1

    The Qt 4.8 documentation on QHash suggested erase keys in hash table like this:

    QHash<QString, int>::iterator i = hash.begin();
    while (i != hash.end()) {
        QHash<QString, int>::iterator prev = i;
        ++i;
        if (prev.key().startsWith("_"))
            hash.erase(prev);
    }
    

    But isn't this snippet of code equivalent to the following:

    QHash<QString, int>::iterator i = hash.begin();
    while (i != hash.end()) {
        if (i.key().startsWith("_"))
            hash.erase(i++);
        else
            i++;
    }
    

    Why bother using the temporary variable prev ? I did some research online and find that the compiler would sometimes reorder the instruction so that it's not that easy to tell when exactly will i get increased. But I think even in the worst case the variable i should get increased before the hash table erase the key? Thus there is no need to use the Qt recommended style.

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 11 Jan 2016, 23:09 last edited by
      #2

      Hi and welcome to devnet,

      To discuss that kind of design recommendation you should rather post your question on the interest mailing list You'll find there Qt's developers/maintainers. This forum is more user oriented.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      B 1 Reply Last reply 12 Jan 2016, 18:02
      0
      • C Offline
        C Offline
        Chris Kawa
        Lifetime Qt Champion
        wrote on 12 Jan 2016, 16:33 last edited by Chris Kawa 1 Dec 2016, 16:36
        #3

        Your version is incorrect. It only increases i when an item is erased. If there is at least one item not starting with _ in your hash then the while loop is infinite.

        The reason the iterator is preserved is that the value pointed by it is possibly erased. You can't then increment an iterator that points to erased value. Thus a copy is made and increased before an item is erased. As an alternative you could use the value returned from erase like this:

        QHash<QString, int>::iterator i = hash.begin();
        while (i != hash.end()) {
            if (i.key().startsWith("_"))
                i = hash.erase(i);
            else
                ++i;
        }
        
        B 1 Reply Last reply 12 Jan 2016, 17:56
        0
        • C Chris Kawa
          12 Jan 2016, 16:33

          Your version is incorrect. It only increases i when an item is erased. If there is at least one item not starting with _ in your hash then the while loop is infinite.

          The reason the iterator is preserved is that the value pointed by it is possibly erased. You can't then increment an iterator that points to erased value. Thus a copy is made and increased before an item is erased. As an alternative you could use the value returned from erase like this:

          QHash<QString, int>::iterator i = hash.begin();
          while (i != hash.end()) {
              if (i.key().startsWith("_"))
                  i = hash.erase(i);
              else
                  ++i;
          }
          
          B Offline
          B Offline
          bigapple
          wrote on 12 Jan 2016, 17:56 last edited by
          #4

          @Chris-Kawa Thank you. Sorry I made the silly mistake here. I have corrected the logic so that the loop will increase the iterator every time.

          I don't agree with what you said about the iterator. The postfix increment is supposed to first increase the iterator i and return the value of the expression `i++' which is the iterator before the increment. I think it's equivalent to:

          //defined inside template QHash<K, V>
          iterator operator++( int ) {
              iterator ret = *this;
              ++*this;
              return ret;
          }
          
          1 Reply Last reply
          0
          • S SGaist
            11 Jan 2016, 23:09

            Hi and welcome to devnet,

            To discuss that kind of design recommendation you should rather post your question on the interest mailing list You'll find there Qt's developers/maintainers. This forum is more user oriented.

            B Offline
            B Offline
            bigapple
            wrote on 12 Jan 2016, 18:02 last edited by
            #5

            Thanks @SGaist for letting me know . I'll definitely do it for my future posts.

            1 Reply Last reply
            0
            • C Offline
              C Offline
              Chris Kawa
              Lifetime Qt Champion
              wrote on 12 Jan 2016, 18:50 last edited by
              #6

              True. I got carried away.
              So the only difference is that if you use prefix increment you do the iterator ret = *this; part manually. With inlining and whatnot I'm pretty sure the optimized result would be almost, if not exactly, the same.

              B 1 Reply Last reply 13 Jan 2016, 16:37
              0
              • C Chris Kawa
                12 Jan 2016, 18:50

                True. I got carried away.
                So the only difference is that if you use prefix increment you do the iterator ret = *this; part manually. With inlining and whatnot I'm pretty sure the optimized result would be almost, if not exactly, the same.

                B Offline
                B Offline
                bigapple
                wrote on 13 Jan 2016, 16:37 last edited by
                #7

                Thanks @Chris-Kawa. Just wanna confirm the correctness.

                1 Reply Last reply
                0

                2/7

                11 Jan 2016, 23:09

                topic:navigator.unread, 5
                • Login

                • Login or register to search.
                2 out of 7
                • First post
                  2/7
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved