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. Iterator as a member: Tree/Graph-like structure
Forum Updated to NodeBB v4.3 + New Features

Iterator as a member: Tree/Graph-like structure

Scheduled Pinned Locked Moved Unsolved C++ Gurus
qlistiteratorsequencegraph
35 Posts 5 Posters 2.7k Views 2 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.
  • P Pl45m4
    10 Jan 2025, 16:13

    @JonB said in Iterator as a member: Tree/Graph-like structure:

    Since @Christian-Ehrlicher said I may not have made it 100% clear. All in all I would probably use

    QMap<int, Task *> map;
    map.insert(task->id, task);
    

    This makes totally sense and I also got what @Christian-Ehrlicher wrote above about a custom "key", but is it really a good idea to map MyTask to members of itself?!
    Is there no other magical way to do it?
    That stopped me from going over this approach in my head any further.
    Because the "fun" thing is that (with a QMap) I currently wouldn't know what to put as value otherwise, when using a key like @Christian-Ehrlicher described before and correctly :))

    I have

    // my current approach task container
    QList<MyTask*> taskList;
    
    // (not included in my example and not relevant for looping the tasks)
    // where "int" equals a valid MyTask::id
    QHash<MyWidget *, int> taskWidgetMap;
    

    so the information what Task has which ID is already stored in MyTask class

    To get somewhere with this, I will try @Christian-Ehrlicher 's approach and your MyTask <--> MyTask::id mapping now and see how it integrates into the rest. ;-)

    Btw: Now I've read through QSet<T> more carefully and figured out that my initial thought (in my head without specifying any data structure) was about something like an ordered (ideally hash-based) one-dimensional structure (= "list", no key-value dict).... which does not existing in this form :)

    So yeah, I will report back later ;-)

    Besides the data struture mess, have you tried my example @JonB @Christian-Ehrlicher ? What do you think? :)

    Highly appreciate all your input and the discussion here :)

    J Offline
    J Offline
    JonB
    wrote on 10 Jan 2025, 16:32 last edited by
    #25

    @Pl45m4

    • Christian's approach of defining a < operator for the Task struct itself is required if and only if you wish to have a Task * as the key for the QMap. Which is what he says you had stated initially.
    • But I don't see why you would want or need that (my Task * is the value, not the key). I just use an int as the key and pass task->id for that at map insert time.

    Up to you.

    P 1 Reply Last reply 10 Jan 2025, 16:39
    0
    • J JonB
      10 Jan 2025, 16:32

      @Pl45m4

      • Christian's approach of defining a < operator for the Task struct itself is required if and only if you wish to have a Task * as the key for the QMap. Which is what he says you had stated initially.
      • But I don't see why you would want or need that (my Task * is the value, not the key). I just use an int as the key and pass task->id for that at map insert time.

      Up to you.

      P Offline
      P Offline
      Pl45m4
      wrote on 10 Jan 2025, 16:39 last edited by
      #26

      @JonB said in Iterator as a member: Tree/Graph-like structure:

      I just use an int as the key and pass task->id for that at map insert time

      Yeah that makes sense... but my concern is/was that I have some redundancy. MyTask::id = key AND also already stored in MyTask (and accessible via something like value().id)...

      Will try it out.


      If debugging is the process of removing software bugs, then programming must be the process of putting them in.

      ~E. W. Dijkstra

      J 1 Reply Last reply 10 Jan 2025, 16:52
      0
      • P Pl45m4
        10 Jan 2025, 16:39

        @JonB said in Iterator as a member: Tree/Graph-like structure:

        I just use an int as the key and pass task->id for that at map insert time

        Yeah that makes sense... but my concern is/was that I have some redundancy. MyTask::id = key AND also already stored in MyTask (and accessible via something like value().id)...

        Will try it out.

        J Offline
        J Offline
        JonB
        wrote on 10 Jan 2025, 16:52 last edited by JonB 1 Oct 2025, 16:52
        #27

        @Pl45m4
        You are saving/losing an int for the key. But even another way to use a QMap you have to provide some key to go with a value. If you use Task * as the key that costs a pointer (even if you also store Task * as the value too) which is actually bigger than an int. Plus your QMap actually goes wrong if you go change what the key pointer points to, or the id inside that, if you change the id in the Task your QMap won't rearrange itself!

        Many times we do key-value pairs like this. I could be wrong, but when, say, you have a database table with a primary (or unique) key/index I don't think that stores a "pointer to" its value somewhere in the row for its data, I think it copies the value to the index and then keeps that in sync if the row changes.

        But if you are happier with the key as a Task * and override the < operator that is fine too.

        1 Reply Last reply
        1
        • C Christian Ehrlicher
          10 Jan 2025, 14:06

          Sorry but I don't understand what you mean - simply replace QMap<MyTask *, whatever> with QMap<Key, whatever> and provide a operator<() for the key (I was wrong above - you don't have to provide a qHash() but a operator <() for a QMap)

          struct Key {
            MyTask *task;
            bool operator <(const Key &o) const
            {
              return  task->id < o.task->id;
            }
          };
          
           QMap<Key, something> myMap;
          
          P Offline
          P Offline
          Pl45m4
          wrote on 10 Jan 2025, 17:50 last edited by
          #28

          @Christian-Ehrlicher said in Iterator as a member: Tree/Graph-like structure:

          simply replace QMap<MyTask *, whatever> with QMap<Key, whatever> and provide a operator<() for the key (I was wrong above - you don't have to provide a qHash() but a operator <() for a QMap)

          struct Key {
            MyTask *task;
            bool operator <(const Key &o) const
            {
              return  task->id < o.task->id;
            }
          };
          
           QMap<Key, something> myMap;
          

          One more thing @Christian-Ehrlicher :
          Is there a reason why you picked an extra struct for the Key instead of using the MyTask::operator < directly?


          If debugging is the process of removing software bugs, then programming must be the process of putting them in.

          ~E. W. Dijkstra

          C 1 Reply Last reply 10 Jan 2025, 17:52
          0
          • P Pl45m4
            10 Jan 2025, 17:50

            @Christian-Ehrlicher said in Iterator as a member: Tree/Graph-like structure:

            simply replace QMap<MyTask *, whatever> with QMap<Key, whatever> and provide a operator<() for the key (I was wrong above - you don't have to provide a qHash() but a operator <() for a QMap)

            struct Key {
              MyTask *task;
              bool operator <(const Key &o) const
              {
                return  task->id < o.task->id;
              }
            };
            
             QMap<Key, something> myMap;
            

            One more thing @Christian-Ehrlicher :
            Is there a reason why you picked an extra struct for the Key instead of using the MyTask::operator < directly?

            C Offline
            C Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on 10 Jan 2025, 17:52 last edited by
            #29

            @Pl45m4 said in Iterator as a member: Tree/Graph-like structure:

            instead of using the MyTask::operator < directly?

            Because this operator would not be used by a QMap<MyTask*, ...> as you store a pointer, not a value.

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

            P 1 Reply Last reply 10 Jan 2025, 17:55
            2
            • C Christian Ehrlicher
              10 Jan 2025, 17:52

              @Pl45m4 said in Iterator as a member: Tree/Graph-like structure:

              instead of using the MyTask::operator < directly?

              Because this operator would not be used by a QMap<MyTask*, ...> as you store a pointer, not a value.

              P Offline
              P Offline
              Pl45m4
              wrote on 10 Jan 2025, 17:55 last edited by
              #30

              @Christian-Ehrlicher

              Ah I see, thanks.


              If debugging is the process of removing software bugs, then programming must be the process of putting them in.

              ~E. W. Dijkstra

              1 Reply Last reply
              0
              • G Offline
                G Offline
                GrecKo
                Qt Champions 2018
                wrote on 10 Jan 2025, 22:00 last edited by
                #31

                How many elements would there be in this container?

                J P 2 Replies Last reply 10 Jan 2025, 22:25
                1
                • G GrecKo
                  10 Jan 2025, 22:00

                  How many elements would there be in this container?

                  J Offline
                  J Offline
                  JonB
                  wrote on 10 Jan 2025, 22:25 last edited by
                  #32

                  @GrecKo
                  :) Unless it's like more than 100, and this is called many times, and the tasks don't take long to run comparatively, I suspect the whole "fast lookup" won't matter much! But maybe still the principle of how you pick up where you left off from.

                  1 Reply Last reply
                  1
                  • G GrecKo
                    10 Jan 2025, 22:00

                    How many elements would there be in this container?

                    P Offline
                    P Offline
                    Pl45m4
                    wrote on 10 Jan 2025, 23:18 last edited by
                    #33

                    @GrecKo

                    Probably 100-200 at max... usually around 50, I would say :)

                    Sure I could use some inefficient for loop and search/compare each value manually, but a more efficient and cleaner way seems more reasonable to me ;)


                    If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                    ~E. W. Dijkstra

                    1 Reply Last reply
                    1
                    • G Offline
                      G Offline
                      GrecKo
                      Qt Champions 2018
                      wrote on 11 Jan 2025, 00:09 last edited by
                      #34

                      An "inefficient" simple for loop may very well be the most efficient after all. When you have 50 elements it won't matter much anyway, pick the container with the friendliest API depending on how you plan to access it.

                      P 1 Reply Last reply 11 Jan 2025, 00:40
                      1
                      • G GrecKo
                        11 Jan 2025, 00:09

                        An "inefficient" simple for loop may very well be the most efficient after all. When you have 50 elements it won't matter much anyway, pick the container with the friendliest API depending on how you plan to access it.

                        P Offline
                        P Offline
                        Pl45m4
                        wrote on 11 Jan 2025, 00:40 last edited by
                        #35

                        @GrecKo said in Iterator as a member: Tree/Graph-like structure:

                        pick the container with the friendliest API depending on how you plan to access it.

                        Still what @Christian-Ehrlicher and @JonB suggested doesn't sound too bad :)
                        Will definitely try it.

                        Similar question: Why is QButtonGroup using a QHash-map for its member buttons? :))
                        I doubt that there ever will be thousands of button widgets in one group :)


                        If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                        ~E. W. Dijkstra

                        1 Reply Last reply
                        1

                        34/35

                        11 Jan 2025, 00:09

                        • Login

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