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 Update on Tuesday, May 27th 2025

creating hash (or list) of member functions

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

    The way class member functions work is that they really are just regular functions that have a hidden implicit this parameter, so in effect it's like Clock::update(instance).

    OMG! But where does C++ tell you this and that you can write code to use it? I had no idea this was "documented" or "supported". I assumed implementation was opaque/abstract.

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

    @JonB said:

    But where does C++ tell you this and that you can write code to use it?

    Well no, you can't currently write it like that. I meant it conceptually. That's just what the compiler does anyway (you can see it e.g. in the mangled function signatures when inspecting C++ library exports).

    Although the so called Uniform Call Syntax has been proposed multiple times over the years, including by Mr. C++ himself: N4474, so you might see it in some future standard version.

    JonBJ 1 Reply Last reply
    1
    • Chris KawaC Chris Kawa

      @JonB said:

      But where does C++ tell you this and that you can write code to use it?

      Well no, you can't currently write it like that. I meant it conceptually. That's just what the compiler does anyway (you can see it e.g. in the mangled function signatures when inspecting C++ library exports).

      Although the so called Uniform Call Syntax has been proposed multiple times over the years, including by Mr. C++ himself: N4474, so you might see it in some future standard version.

      JonBJ Online
      JonBJ Online
      JonB
      wrote on last edited by JonB
      #19

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