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?

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 last edited by bigapple
    #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
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on 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
      0
      • Chris KawaC Offline
        Chris KawaC Offline
        Chris Kawa
        Lifetime Qt Champion
        wrote on last edited by Chris Kawa
        #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
        0
        • Chris KawaC Chris Kawa

          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 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
          • SGaistS SGaist

            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 last edited by
            #5

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

            1 Reply Last reply
            0
            • Chris KawaC Offline
              Chris KawaC Offline
              Chris Kawa
              Lifetime Qt Champion
              wrote on 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
              0
              • Chris KawaC Chris Kawa

                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 last edited by
                #7

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

                1 Reply Last reply
                0

                • Login

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