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

creating hash (or list) of member functions

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