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. creating hash (or list) of member functions
Qt 6.11 is out! See what's new in the release blog

creating hash (or list) of member functions

Scheduled Pinned Locked Moved Solved C++ Gurus
30 Posts 5 Posters 8.0k 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.
  • Chris KawaC Chris Kawa

    @JonB said:

    But I just know it's going to look complicated.... :(

    It does look a bit complicated, but it has to deal with variable number of perfectly forwarded arguments and a lot of weird corner cases users come up with. Also it's the standard library, so it's mangled with all those underscore names and defensive programming style, but if you squint a little you'll see it basically returns a class with operator() like I mentioned.

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

    @Chris-Kawa
    Thanks. You gotta love hardcore C++, it's so... simple and clean.

    mzimmersM 1 Reply Last reply
    0
    • JonBJ JonB

      @Chris-Kawa
      Thanks. You gotta love hardcore C++, it's so... simple and clean.

      mzimmersM Offline
      mzimmersM Offline
      mzimmers
      wrote on last edited by
      #22

      @JonB said in creating hash (or list) of member functions:

      @Chris-Kawa
      Thanks. You gotta love hardcore C++, it's so... simple and clean.

      Now, now...no sarcasm.

      But yeah...wouldn't you love to have today's compute resources available for solving the problems of 30 years ago?

      1 Reply Last reply
      0
      • JonBJ JonB

        @mzimmers said in creating hash (or list) of member functions:

        but I wonder if you could give me an explanation for the use of the std::bind. The list is just a list of QObjects; how does this "attach" the callback function?

        All of this in place of the typedef void (*clientSlot)(), with C life used to be so simple :) We can't use that to call a C++ class member function on an instance. So...

        std::function<void()>
        

        I can be used to call a C++ class member method.

        registerClient(T* client, void(T::*cs)())
        

        Here's my client object (of a certain type), and here is the class member function.

        clients.push_back(std::bind(cs, client));
        

        Creates and pushes an object which, when invoked, will call cs(client). Which turns out to be the same as client->cs(). Which I am just about to question @Chris-Kawa on...!

        J.HilkJ Offline
        J.HilkJ Offline
        J.Hilk
        Moderators
        wrote on last edited by
        #23

        @JonB said in creating hash (or list) of member functions:

        All of this in place of the typedef void (*clientSlot)(), with C life used to be so simple :) We can't use that to call a C++ class member function on an instance

        who says you can't ?

        #include <array>
        
        class SomeClass : public QObject
        {
            Q_OBJECT
            typedef void (SomeClass::*SomeClassFunction)();
        
            std::array<SomeClassFunction,3> arrayOfSignalsPointers{&SomeClass::signal1,&SomeClass::signal2, &SomeClass::signal3};
            std::array<SomeClassFunction, 3> arrayOfSlotsPointers{&SomeClass::slot1, &SomeClass::slot2, &SomeClass::slot3};
        
        public:
            explicit SomeClass(QObject *parent = nullptr) : QObject(parent)
            {
                QObject::connect(this, &SomeClass::signal1, this, &SomeClass::slot1);
                QObject::connect(this, &SomeClass::signal2, this, &SomeClass::slot2);
                QObject::connect(this, &SomeClass::signal3, this, &SomeClass::slot3);
        
                qDebug() << "Emit all signals";
                for(auto entry : arrayOfSignalsPointers){
                    (this->*entry)();
                }
        
                qDebug() << "Call all slots directly";
                for(auto entry : arrayOfSlotsPointers){
                    (this->*entry)();
                }
            }
        
        signals:
            void signal1();
            void signal2();
            void signal3();
        
        public slots:
            void slot1(){qDebug() <<  Q_FUNC_INFO;}
            void slot2(){qDebug() <<  Q_FUNC_INFO;}
            void slot3(){qDebug() <<  Q_FUNC_INFO;}
        };
        

        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


        Q: What's that?
        A: It's blue light.
        Q: What does it do?
        A: It turns blue.

        JonBJ 1 Reply Last reply
        1
        • J.HilkJ J.Hilk

          @JonB said in creating hash (or list) of member functions:

          All of this in place of the typedef void (*clientSlot)(), with C life used to be so simple :) We can't use that to call a C++ class member function on an instance

          who says you can't ?

          #include <array>
          
          class SomeClass : public QObject
          {
              Q_OBJECT
              typedef void (SomeClass::*SomeClassFunction)();
          
              std::array<SomeClassFunction,3> arrayOfSignalsPointers{&SomeClass::signal1,&SomeClass::signal2, &SomeClass::signal3};
              std::array<SomeClassFunction, 3> arrayOfSlotsPointers{&SomeClass::slot1, &SomeClass::slot2, &SomeClass::slot3};
          
          public:
              explicit SomeClass(QObject *parent = nullptr) : QObject(parent)
              {
                  QObject::connect(this, &SomeClass::signal1, this, &SomeClass::slot1);
                  QObject::connect(this, &SomeClass::signal2, this, &SomeClass::slot2);
                  QObject::connect(this, &SomeClass::signal3, this, &SomeClass::slot3);
          
                  qDebug() << "Emit all signals";
                  for(auto entry : arrayOfSignalsPointers){
                      (this->*entry)();
                  }
          
                  qDebug() << "Call all slots directly";
                  for(auto entry : arrayOfSlotsPointers){
                      (this->*entry)();
                  }
              }
          
          signals:
              void signal1();
              void signal2();
              void signal3();
          
          public slots:
              void slot1(){qDebug() <<  Q_FUNC_INFO;}
              void slot2(){qDebug() <<  Q_FUNC_INFO;}
              void slot3(){qDebug() <<  Q_FUNC_INFO;}
          };
          
          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #24

          @J-Hilk said in creating hash (or list) of member functions:

          typedef void (SomeClass::*SomeClassFunction)();

          I said that you cannot use typedef void (*clientSlot)();, as the OP wrote and one would in C, to call a C++ member function. And you can't: as you show you need ClassName::*function not just plain *function.

          Having said that, I was nonetheless not aware that you can use that to get a member function's address and then call (instance->*memberFunctionPointer)(). Thank you for clarifying.

          So.... all this std::function<> and particularly std::bind() looks like the usual C++ "why would you want to write something simple when you can wrap it up to be complicated"? ;-)

          Chris KawaC 1 Reply Last reply
          1
          • JonBJ JonB

            @J-Hilk said in creating hash (or list) of member functions:

            typedef void (SomeClass::*SomeClassFunction)();

            I said that you cannot use typedef void (*clientSlot)();, as the OP wrote and one would in C, to call a C++ member function. And you can't: as you show you need ClassName::*function not just plain *function.

            Having said that, I was nonetheless not aware that you can use that to get a member function's address and then call (instance->*memberFunctionPointer)(). Thank you for clarifying.

            So.... all this std::function<> and particularly std::bind() looks like the usual C++ "why would you want to write something simple when you can wrap it up to be complicated"? ;-)

            Chris KawaC Offline
            Chris KawaC Offline
            Chris Kawa
            Lifetime Qt Champion
            wrote on last edited by
            #25

            @JonB said:

            So.... all this std::function<> and particularly std::bind() looks like the usual C++ "why would you want to write something simple when you can wrap it up to be complicated"? ;-)

            No, it's a way to be generic. To write typedef void (SomeClass::*SomeClassFunction)() you have to hardcode SomeClass i.e. know it up front. Notice that what @J-Hilk posted will work with one particular class only. I know he just shows how to call a member function from a pointer and that's fine, but it doesn't do much for the original problem.
            std::function doesn't care. It just takes any functor you give it and std::bind creates a functor from anything callable you give it.

            JonBJ 1 Reply Last reply
            2
            • Chris KawaC Chris Kawa

              @JonB said:

              So.... all this std::function<> and particularly std::bind() looks like the usual C++ "why would you want to write something simple when you can wrap it up to be complicated"? ;-)

              No, it's a way to be generic. To write typedef void (SomeClass::*SomeClassFunction)() you have to hardcode SomeClass i.e. know it up front. Notice that what @J-Hilk posted will work with one particular class only. I know he just shows how to call a member function from a pointer and that's fine, but it doesn't do much for the original problem.
              std::function doesn't care. It just takes any functor you give it and std::bind creates a functor from anything callable you give it.

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

              @Chris-Kawa
              Ah yes, I get it.

              Modern C++ programming is hugely about templates. But, correct me if I am wrong, C++ did not start out with templates, did it?

              J.HilkJ 1 Reply Last reply
              0
              • JonBJ JonB

                @Chris-Kawa
                Ah yes, I get it.

                Modern C++ programming is hugely about templates. But, correct me if I am wrong, C++ did not start out with templates, did it?

                J.HilkJ Offline
                J.HilkJ Offline
                J.Hilk
                Moderators
                wrote on last edited by
                #27

                @JonB proposed in 1988, realised in 1990 so a decade after the "initial commit" :P


                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

                JonBJ Chris KawaC 2 Replies Last reply
                2
                • J.HilkJ J.Hilk

                  @JonB proposed in 1988, realised in 1990 so a decade after the "initial commit" :P

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

                  @J-Hilk Ah, thanks, that is much earlier than I realized, I thought more like 10 years later.

                  1 Reply Last reply
                  0
                  • J.HilkJ J.Hilk

                    @JonB proposed in 1988, realised in 1990 so a decade after the "initial commit" :P

                    Chris KawaC Offline
                    Chris KawaC Offline
                    Chris Kawa
                    Lifetime Qt Champion
                    wrote on last edited by
                    #29

                    @J-Hilk Where "initial commit" at that time would probably be Stroustrup saving it to a big floppy and physically carrying it to the cubicle of his coworkers. Good old times :D

                    JonBJ 1 Reply Last reply
                    0
                    • Chris KawaC Chris Kawa

                      @J-Hilk Where "initial commit" at that time would probably be Stroustrup saving it to a big floppy and physically carrying it to the cubicle of his coworkers. Good old times :D

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

                      @Chris-Kawa

                      We were beyond floppies by then. The first computer I used had 10.5 inch (I think, unless it was only 8 inch) floppies, https://www.computinghistory.org.uk/det/10247/Nord-ND305-355-Floppy-Disk/ :)

                      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