Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. Using QList [] operator in const methods
Forum Updated to NodeBB v4.3 + New Features

Using QList [] operator in const methods

Scheduled Pinned Locked Moved Solved C++ Gurus
10 Posts 5 Posters 123 Views 3 Watching
  • 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.
  • JonBJ Offline
    JonBJ Offline
    JonB
    wrote last edited by JonB
    #1

    As we know, you cannot use QList [] operator in a method which is const, even when reading not trying to write a value. You must use at().

    OTOH C++ has no problems with native array [] operator.

    void Class::method() const
    {
        z = qlistMember.at(0);    // OK
        z = qlistMember[0];    // Nope
        z = nativeArray[0];    // Yep
        nativeArray[0] = z;    // Nope
    }
    

    Personally I hate having to write at(i) instead of [i] to read a QList value in a const function. I would prefer having the C++ native array context semantics.

    Why is this either not available or not possible for a QList? Could it have been done when they wrote operator overloads by treating const differently, and for whatever reason Qt has not implemented it, or is there a fundamental difference in C++ handling of const/reads for native array [] versus what you can write for your own operator overloads.

    Meanwhile I had a quick look at what std::vector does for this. It too has [] operator and an at() method. But if I understand right they differ for bounds checking not for read vs write? You can use their [] operator in a const/read context.

    UPDATE
    Investigating from @Kent-Dorfman's reply below, I think I am seeing that QList [] operator is allowed (for reading) on a const QList after all, making my question irrelevant? But is this a change in Qt 6.x over 5.x??

    1 Reply Last reply
    0
    • JonBJ Offline
      JonBJ Offline
      JonB
      wrote last edited by JonB
      #4

      Well, apologies, it seems this is non-question! I have gone back as far as the docs for Qt 5.10, which I think was around when I started Qt, and I still see there is a const T &QList::operator[](int i) const

      Same as at().

      So it has apparently always been possible to write z = qlistMember[0]; in a const method! Yet at some point I thought I found this was not possible and made myself write at() for all QList reads in const methods always. Maybe it was for some other type than QList with a [] operator which did not offer a const overload and I got it fixed in my head...?

      Christian EhrlicherC 1 Reply Last reply
      1
      • Kent-DorfmanK Offline
        Kent-DorfmanK Offline
        Kent-Dorfman
        wrote last edited by Kent-Dorfman
        #2

        Can you explain further? the const thing confuses me.

        The bigger picture though is that lists are generally linked lists while vectors and arrays create adjacent cells across contiguous memory ranged. So non-overloaded [] will work on arrays (and vectors with the right type cast), but must be overloaded to work on a list.

        Looks like in 6.9 there are actually two versions of QList::[]

        QList<T>::reference 	operator[](qsizetype i)
        QList<T>::const_reference 	operator[](qsizetype i) const
        
        JonBJ 1 Reply Last reply
        1
        • Kent-DorfmanK Kent-Dorfman

          Can you explain further? the const thing confuses me.

          The bigger picture though is that lists are generally linked lists while vectors and arrays create adjacent cells across contiguous memory ranged. So non-overloaded [] will work on arrays (and vectors with the right type cast), but must be overloaded to work on a list.

          Looks like in 6.9 there are actually two versions of QList::[]

          QList<T>::reference 	operator[](qsizetype i)
          QList<T>::const_reference 	operator[](qsizetype i) const
          
          JonBJ Offline
          JonBJ Offline
          JonB
          wrote last edited by JonB
          #3

          @Kent-Dorfman said in Using QList [] operator in const methods:

          Can you explain further? the const thing confuses me.

          Don't know what more to say than [Note: I have corrected my earlier method code to make it clear the method is const, which I failed to do, sorry if that confused.]

          void Class::method() const
          {
              z = qlistMember[0];    // Nope
              z = nativeArray[0];    // Yep
          }
          

          You cannot use QList [] operator even to read a value from a QList where the list is const/read-only, either by declaring it const QList<>[] explicitly or by it being a class member variable not itself const but inside a const member method, so it is implicitly const in that method.

          Linked lists vs contiguous memory is not in itself germane.

          Looks like in 6.9 there are actually two versions of QList::[]

          Well that would make a huge difference, that's exactly what I would have liked. And I believe I can use z = qlistMember[0]; // Nope in my Qt 6.4 or 6.5 after all. But I am "pretty sure" this was not possible in Qt 5.x, was it? Did this change??

          1 Reply Last reply
          0
          • JonBJ Offline
            JonBJ Offline
            JonB
            wrote last edited by JonB
            #4

            Well, apologies, it seems this is non-question! I have gone back as far as the docs for Qt 5.10, which I think was around when I started Qt, and I still see there is a const T &QList::operator[](int i) const

            Same as at().

            So it has apparently always been possible to write z = qlistMember[0]; in a const method! Yet at some point I thought I found this was not possible and made myself write at() for all QList reads in const methods always. Maybe it was for some other type than QList with a [] operator which did not offer a const overload and I got it fixed in my head...?

            Christian EhrlicherC 1 Reply Last reply
            1
            • JonBJ JonB has marked this topic as solved
            • JonBJ JonB

              Well, apologies, it seems this is non-question! I have gone back as far as the docs for Qt 5.10, which I think was around when I started Qt, and I still see there is a const T &QList::operator[](int i) const

              Same as at().

              So it has apparently always been possible to write z = qlistMember[0]; in a const method! Yet at some point I thought I found this was not possible and made myself write at() for all QList reads in const methods always. Maybe it was for some other type than QList with a [] operator which did not offer a const overload and I got it fixed in my head...?

              Christian EhrlicherC Offline
              Christian EhrlicherC Offline
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote last edited by
              #5

              @JonB said in Using QList [] operator in const methods:

              Maybe it was for some other type than QList with a [] operator which did not offer a const overload and I got it fixed in my head...?

              Yes. QMap and QHash.

              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
              Visit the Qt Academy at https://academy.qt.io/catalog

              JonBJ 1 Reply Last reply
              1
              • Christian EhrlicherC Christian Ehrlicher

                @JonB said in Using QList [] operator in const methods:

                Maybe it was for some other type than QList with a [] operator which did not offer a const overload and I got it fixed in my head...?

                Yes. QMap and QHash.

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote last edited by
                #6

                @Christian-Ehrlicher
                Yes, it could have been that I extrapolated from those to QList/QVectors when that was not the case. I am still surprised that I was so sure it was the case. Anyway I am much happier now that I know that I can use [] for read on const lists/vectors instead of having to type at(), going forward from now.

                1 Reply Last reply
                0
                • GrecKoG Offline
                  GrecKoG Offline
                  GrecKo
                  Qt Champions 2018
                  wrote last edited by
                  #7

                  QMap and QHash do offer a const operator[]. std::map is the one without the const overload.
                  QMap does this by changing the return type from T& to T. A conscious choice was made not to do that in the standard library.

                  1 Reply Last reply
                  1
                  • Kent-DorfmanK Offline
                    Kent-DorfmanK Offline
                    Kent-Dorfman
                    wrote last edited by
                    #8

                    My spidey sense was telling this has something to do with returning a reference instead of a copy. I could picture grabbing a reference to an entry in the container and then that element being deleted, and Boom! stuff breaks.

                    S 1 Reply Last reply
                    0
                    • Kent-DorfmanK Kent-Dorfman

                      My spidey sense was telling this has something to do with returning a reference instead of a copy. I could picture grabbing a reference to an entry in the container and then that element being deleted, and Boom! stuff breaks.

                      S Offline
                      S Offline
                      SimonSchroeder
                      wrote last edited by
                      #9

                      @Kent-Dorfman said in Using QList [] operator in const methods:

                      My spidey sense was telling this has something to do with returning a reference instead of a copy. I could picture grabbing a reference to an entry in the container and then that element being deleted, and Boom! stuff breaks.

                      You'll only get a const reference returned if the QList is const (inside the currently visible scope). Nobody is going to change it while it is const (I know, it is a simplified assumption without any multithreading involved). You also have to be explicit in having a const reference instead of a copy; auto or just T (T being the type inside the QList) will give you a copy. You have to add const and & yourself. And hopefully you know what you are doing if you do this. Usually, this is not a problem if your const reference is not a member variable (and reference member variables can only be assigned once inside the constructor which is why you'll rarely see them in the wild).

                      Even if operator[](int) const returns a copy you have the exact same possible race condition in a multithreading environment. The only advantage is that it is fewer lines of code where this might occur.

                      Kent-DorfmanK 1 Reply Last reply
                      1
                      • S SimonSchroeder

                        @Kent-Dorfman said in Using QList [] operator in const methods:

                        My spidey sense was telling this has something to do with returning a reference instead of a copy. I could picture grabbing a reference to an entry in the container and then that element being deleted, and Boom! stuff breaks.

                        You'll only get a const reference returned if the QList is const (inside the currently visible scope). Nobody is going to change it while it is const (I know, it is a simplified assumption without any multithreading involved). You also have to be explicit in having a const reference instead of a copy; auto or just T (T being the type inside the QList) will give you a copy. You have to add const and & yourself. And hopefully you know what you are doing if you do this. Usually, this is not a problem if your const reference is not a member variable (and reference member variables can only be assigned once inside the constructor which is why you'll rarely see them in the wild).

                        Even if operator[](int) const returns a copy you have the exact same possible race condition in a multithreading environment. The only advantage is that it is fewer lines of code where this might occur.

                        Kent-DorfmanK Offline
                        Kent-DorfmanK Offline
                        Kent-Dorfman
                        wrote last edited by
                        #10

                        @SimonSchroeder said in Using QList [] operator in const methods:

                        Even if operator[](int) const returns a copy you have the exact same possible race condition in a multithreading environment. The only advantage is that it is fewer lines of code where this might occur.

                        Multithreading seems an irrelevant point though because the competent programmer understands that accessing a shared resource needs a mutex, so if safe programming processes are observed then there is no race condition.

                        re const vs non-const: totally agree and get it. It's the way things are...however, I do sometimes wish nothing was ever const and everything was mutable. :^)

                        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