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
Forum Updated to NodeBB v4.3 + New Features

creating hash (or list) of member functions

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

    @Chris-Kawa said in creating hash (or list) of member functions:

    Well no, you can't currently write it like that. I meant it conceptually.

    Oh, right! For a while there I thought you were saying literally.

    I suppose I ought go look at what magic std::bind() actually does, then it would be clear. But I just know it's going to look complicated.... :(

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

    @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 1 Reply Last reply
    1
    • 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