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. Conflict in Qt Doc on the usage of foreach keyword and range-based for?
QtWS25 Last Chance

Conflict in Qt Doc on the usage of foreach keyword and range-based for?

Scheduled Pinned Locked Moved Solved General and Desktop
documentationforeachfor loopcontainercontainers
7 Posts 3 Posters 1.4k 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.
  • X Offline
    X Offline
    Xeonacid
    wrote on last edited by Xeonacid
    #1

    Hi there!
    I'm a newbie to Qt containers.

    https://doc.qt.io/qt-5/containers.html#the-foreach-keyword
    This page says If in doubt, prefer foreach for Qt containers, and range based for for STL ones.
    https://doc.qt.io/qt-5/qtglobal.html#foreach
    But this says Note: Since Qt 5.7, the use of this macro is discouraged. It will be removed in a future version of Qt. Please use C++11 range-for, possibly with qAsConst(), as needed.
    This seems to be a conflict?

    If it's not, could you explain the typical usage of both?
    I've learned that range-based for might force a Qt container to detach, whereas foreach would not and Since foreach creates a copy of the container, using a non-const reference for the variable does not allow you to modify the original container. It only affects the copy, which is probably not what you want.
    But I'm still having this doubt.

    Thanks!

    1 Reply Last reply
    0
    • sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by
      #2

      It will be removed in a future version of Qt

      There has actually been a decision made to cancel this removal. foreach is still available in Qt 6.

      This seems to be a conflict?

      On first sight yes, but in reality - no. C++ ranged for is recommended for Qt and STL containers, but if you are unsure how to use it properly - use foreach as it's safer and allows you to iterate even while the container is chaning.

      If it's not, could you explain the typical usage of both?

      foreach - I don't use it anymore. But in general, you can use it safely with all Qt containers. It will be efficient and safe. If you use it on STL containers, you will experience a performance hit (poor performance).

      ranged for - I use it for both STL and Qt containers. The only thing to remember is that Qt containers have to be const, like this:

      for (const auto &item : qAsConst(list)) {
      }
      

      The item can be mutable. But the list has to be const, otherwise the container will detach and do a deep copy.

      Other than that, ranged for is good for all container types, it's fast and compilers can optimize it well.

      I need to add one final hint, though: for small containers, it all does not matter much. Modern computers are so fast, that if you use for wrongly, the performance penalty will be in nanoseconds or miliseconds tops. Only for big containers (hundreds, thousands of items etc.) it becomes important to use the loop correctly.

      (Z(:^

      JonBJ X 2 Replies Last reply
      5
      • sierdzioS sierdzio

        It will be removed in a future version of Qt

        There has actually been a decision made to cancel this removal. foreach is still available in Qt 6.

        This seems to be a conflict?

        On first sight yes, but in reality - no. C++ ranged for is recommended for Qt and STL containers, but if you are unsure how to use it properly - use foreach as it's safer and allows you to iterate even while the container is chaning.

        If it's not, could you explain the typical usage of both?

        foreach - I don't use it anymore. But in general, you can use it safely with all Qt containers. It will be efficient and safe. If you use it on STL containers, you will experience a performance hit (poor performance).

        ranged for - I use it for both STL and Qt containers. The only thing to remember is that Qt containers have to be const, like this:

        for (const auto &item : qAsConst(list)) {
        }
        

        The item can be mutable. But the list has to be const, otherwise the container will detach and do a deep copy.

        Other than that, ranged for is good for all container types, it's fast and compilers can optimize it well.

        I need to add one final hint, though: for small containers, it all does not matter much. Modern computers are so fast, that if you use for wrongly, the performance penalty will be in nanoseconds or miliseconds tops. Only for big containers (hundreds, thousands of items etc.) it becomes important to use the loop correctly.

        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by
        #3

        @sierdzio
        The following type of construct does not detach/copy, does it?

        const QVector<int> &intVec;
        for (int i : intVec)
        
        sierdzioS 1 Reply Last reply
        0
        • JonBJ JonB

          @sierdzio
          The following type of construct does not detach/copy, does it?

          const QVector<int> &intVec;
          for (int i : intVec)
          
          sierdzioS Offline
          sierdzioS Offline
          sierdzio
          Moderators
          wrote on last edited by
          #4

          @JonB said in Conflict in Qt Doc on the usage of foreach keyword and range-based for?:

          @sierdzio
          The following type of construct does not detach/copy, does it?

          const QVector<int> &intVec;
          for (int i : intVec)
          

          This is safe, yes.

          (Z(:^

          1 Reply Last reply
          1
          • sierdzioS sierdzio

            It will be removed in a future version of Qt

            There has actually been a decision made to cancel this removal. foreach is still available in Qt 6.

            This seems to be a conflict?

            On first sight yes, but in reality - no. C++ ranged for is recommended for Qt and STL containers, but if you are unsure how to use it properly - use foreach as it's safer and allows you to iterate even while the container is chaning.

            If it's not, could you explain the typical usage of both?

            foreach - I don't use it anymore. But in general, you can use it safely with all Qt containers. It will be efficient and safe. If you use it on STL containers, you will experience a performance hit (poor performance).

            ranged for - I use it for both STL and Qt containers. The only thing to remember is that Qt containers have to be const, like this:

            for (const auto &item : qAsConst(list)) {
            }
            

            The item can be mutable. But the list has to be const, otherwise the container will detach and do a deep copy.

            Other than that, ranged for is good for all container types, it's fast and compilers can optimize it well.

            I need to add one final hint, though: for small containers, it all does not matter much. Modern computers are so fast, that if you use for wrongly, the performance penalty will be in nanoseconds or miliseconds tops. Only for big containers (hundreds, thousands of items etc.) it becomes important to use the loop correctly.

            X Offline
            X Offline
            Xeonacid
            wrote on last edited by Xeonacid
            #5

            @sierdzio Thanks for your reply!
            But I'm still having some questions:
            1.

            The item can be mutable. But the list has to be const,

            What does this mean? How can item be mutable when list is const? Are you saying about mutable member of item?

            2.

            otherwise the container will detach and do a deep copy.

            When will the container detach? Will it immediately detach when I use a non-const reference on its item?

            3.
            Will foreach do a deep copy if list is not const? If not, why not?
            I've read the source code of Q_FOREACH in qglobal.h. Expect that it copy the container first, it seems much like what ranged for really do then (using begin() and end()), am I wrong?

            sierdzioS 1 Reply Last reply
            0
            • X Xeonacid

              @sierdzio Thanks for your reply!
              But I'm still having some questions:
              1.

              The item can be mutable. But the list has to be const,

              What does this mean? How can item be mutable when list is const? Are you saying about mutable member of item?

              2.

              otherwise the container will detach and do a deep copy.

              When will the container detach? Will it immediately detach when I use a non-const reference on its item?

              3.
              Will foreach do a deep copy if list is not const? If not, why not?
              I've read the source code of Q_FOREACH in qglobal.h. Expect that it copy the container first, it seems much like what ranged for really do then (using begin() and end()), am I wrong?

              sierdzioS Offline
              sierdzioS Offline
              sierdzio
              Moderators
              wrote on last edited by
              #6

              @Xeonacid said in Conflict in Qt Doc on the usage of foreach keyword and range-based for?:

              @sierdzio Thanks for your reply!
              But I'm still having some questions:
              1.

              The item can be mutable. But the list has to be const,

              What does this mean? How can item be mutable when list is const? Are you saying about mutable member of item?

              Item can be a non-const copy.

              const QVector<int> &intVec;
              for (int item : intVect) {
                // Item can change here! But it is a COPY, it won't affect the container
                item += 42;
              }
              

              2.

              otherwise the container will detach and do a deep copy.

              When will the container detach? Will it immediately detach when I use a non-const reference on its item?

              I think the detach happens when you enter the loop, even if you use a const reference to the item. That's why it's super important to keep the container const. More info with all the gory details: https://www.kdab.com/goodbye-q_foreach/

              3.
              Will foreach do a deep copy if list is not const? If not, why not?
              I've read the source code of Q_FOREACH in qglobal.h. It seems much like what ranged for do really (using begin() and end()), am I wrong?

              As far as I know, it will not do a deep copy unless absolutely necessary.

              (Z(:^

              X 1 Reply Last reply
              1
              • sierdzioS sierdzio

                @Xeonacid said in Conflict in Qt Doc on the usage of foreach keyword and range-based for?:

                @sierdzio Thanks for your reply!
                But I'm still having some questions:
                1.

                The item can be mutable. But the list has to be const,

                What does this mean? How can item be mutable when list is const? Are you saying about mutable member of item?

                Item can be a non-const copy.

                const QVector<int> &intVec;
                for (int item : intVect) {
                  // Item can change here! But it is a COPY, it won't affect the container
                  item += 42;
                }
                

                2.

                otherwise the container will detach and do a deep copy.

                When will the container detach? Will it immediately detach when I use a non-const reference on its item?

                I think the detach happens when you enter the loop, even if you use a const reference to the item. That's why it's super important to keep the container const. More info with all the gory details: https://www.kdab.com/goodbye-q_foreach/

                3.
                Will foreach do a deep copy if list is not const? If not, why not?
                I've read the source code of Q_FOREACH in qglobal.h. It seems much like what ranged for do really (using begin() and end()), am I wrong?

                As far as I know, it will not do a deep copy unless absolutely necessary.

                X Offline
                X Offline
                Xeonacid
                wrote on last edited by
                #7

                @sierdzio Many thanks!

                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