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.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.
  • 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 Offline
    JonBJ Offline
    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 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