Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. generalize a c++ method
Qt 6.11 is out! See what's new in the release blog

generalize a c++ method

Scheduled Pinned Locked Moved Solved General and Desktop
34 Posts 5 Posters 8.5k Views 2 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.
  • jsulmJ jsulm

    @LeLev Please take a closer look at the snippet I provided before:

    typedef void (T::*MethodPtr) ();
    MethodPtr method = &T::MethodA;
    T *obj = new T();
    obj->*method();
    

    Your syntax is not even correct as you have to use & to get a pointer not *
    So in your case something like

    class A
    {
        typedef void (A::*MethodPtr) ();
        void nIndexUpdated() {}
        void uaSub(..., MethodPtr ptr) {
            this->*ptr();
        }
    
        // Somewhere inside class A you call uaSub
        uaSub(/*params*/, &A::nIndexUpdated);
    }
    
    ODБOïO Offline
    ODБOïO Offline
    ODБOï
    wrote on last edited by ODБOï
    #17

    @jsulm
    thank you so much for the help you provide.
    Unfortunately i'm so bad, i can't make this work

    class MachineBackend : public QObject
    {
        typedef void (MachineBackend::*MethodPtr) ();
        Q_OBJECT
    
    void nIndexUpdated(QOpcUa::NodeAttribute attr, const QVariant &value){...}
    
    void uaSub2(QScopedPointer<QOpcUaNode>&node, QString nodeId, MethodPtr updateHandlerPtr){
           
           this->*updateHandlerPtr(); // < error here 
    
        }
    };
    

    called object type 'MachineBackend ::MethodPtr' (aka 'void (MachineBackend ::*)()' ) is not a function or function pointer

    jsulmJ 1 Reply Last reply
    0
    • ODБOïO ODБOï

      @jsulm
      thank you so much for the help you provide.
      Unfortunately i'm so bad, i can't make this work

      class MachineBackend : public QObject
      {
          typedef void (MachineBackend::*MethodPtr) ();
          Q_OBJECT
      
      void nIndexUpdated(QOpcUa::NodeAttribute attr, const QVariant &value){...}
      
      void uaSub2(QScopedPointer<QOpcUaNode>&node, QString nodeId, MethodPtr updateHandlerPtr){
             
             this->*updateHandlerPtr(); // < error here 
      
          }
      };
      

      called object type 'MachineBackend ::MethodPtr' (aka 'void (MachineBackend ::*)()' ) is not a function or function pointer

      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #18

      @LeLev Try

      this->updateHandlerPtr();
      
      ODБOïO 1 Reply Last reply
      1
      • jsulmJ jsulm

        @LeLev Try

        this->updateHandlerPtr();
        
        ODБOïO Offline
        ODБOïO Offline
        ODБOï
        wrote on last edited by
        #19

        @jsulm said in generalize a c++ method:

        this->updateHandlerPtr();

        yes i did also, in that case error is :

        no member named 'updateHandlerPtr' in 'MachineBackend '
        which is true

        jsulmJ 1 Reply Last reply
        0
        • ODБOïO ODБOï

          @jsulm said in generalize a c++ method:

          this->updateHandlerPtr();

          yes i did also, in that case error is :

          no member named 'updateHandlerPtr' in 'MachineBackend '
          which is true

          jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #20

          @LeLev This should compile:

          (this->*updateHandlerPtr)();
          

          Method pointers are a mess :-)

          1 Reply Last reply
          2
          • ODБOïO Offline
            ODБOïO Offline
            ODБOï
            wrote on last edited by
            #21

            yes now it doas. awesome ! thank you so much!

            class MachineBackend : public QObject
            {
                typedef void (MachineBackend::*MethodPtr) ();
                Q_OBJECT
            
            void nIndexUpdated(QOpcUa::NodeAttribute attr, const QVariant &value){...}
            
            void uaSub2(QScopedPointer<QOpcUaNode>&node, QString nodeId, MethodPtr updateHandlerPtr){
                   
                   (this->*updateHandlerPtr)();
            
                }
            };
            
            
            
            

            there is still an issue in the usSub() call

            //  Somewhere inside class
              uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex", MachineBackend::nIndexUpdated);  // << error
            //
            

            error : reference to non-static member function must be called

            im trying every possible syntax right now ...

            jsulmJ 2 Replies Last reply
            0
            • ODБOïO ODБOï

              yes now it doas. awesome ! thank you so much!

              class MachineBackend : public QObject
              {
                  typedef void (MachineBackend::*MethodPtr) ();
                  Q_OBJECT
              
              void nIndexUpdated(QOpcUa::NodeAttribute attr, const QVariant &value){...}
              
              void uaSub2(QScopedPointer<QOpcUaNode>&node, QString nodeId, MethodPtr updateHandlerPtr){
                     
                     (this->*updateHandlerPtr)();
              
                  }
              };
              
              
              
              

              there is still an issue in the usSub() call

              //  Somewhere inside class
                uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex", MachineBackend::nIndexUpdated);  // << error
              //
              

              error : reference to non-static member function must be called

              im trying every possible syntax right now ...

              jsulmJ Offline
              jsulmJ Offline
              jsulm
              Lifetime Qt Champion
              wrote on last edited by
              #22

              @LeLev said in generalize a c++ method:

              uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex", MachineBackend::nIndexUpdated);

              uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex", &MachineBackend::nIndexUpdated);
              
              ODБOïO 1 Reply Last reply
              1
              • ODБOïO ODБOï

                yes now it doas. awesome ! thank you so much!

                class MachineBackend : public QObject
                {
                    typedef void (MachineBackend::*MethodPtr) ();
                    Q_OBJECT
                
                void nIndexUpdated(QOpcUa::NodeAttribute attr, const QVariant &value){...}
                
                void uaSub2(QScopedPointer<QOpcUaNode>&node, QString nodeId, MethodPtr updateHandlerPtr){
                       
                       (this->*updateHandlerPtr)();
                
                    }
                };
                
                
                
                

                there is still an issue in the usSub() call

                //  Somewhere inside class
                  uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex", MachineBackend::nIndexUpdated);  // << error
                //
                

                error : reference to non-static member function must be called

                im trying every possible syntax right now ...

                jsulmJ Offline
                jsulmJ Offline
                jsulm
                Lifetime Qt Champion
                wrote on last edited by
                #23

                @LeLev This small example works for me:

                #include <iostream>
                
                class A
                {
                public:
                    typedef void (A::*MethodPtr) ();
                    void someMethod() { std::cout << "Hallo!" << std::endl; }
                    void uaSub2(MethodPtr updateHandlerPtr){
                       (this->* updateHandlerPtr)();
                    }
                };
                
                int main()
                {
                    A a;
                    a.uaSub2(&A::someMethod); 
                    return 0;
                }
                
                1 Reply Last reply
                1
                • jsulmJ jsulm

                  @LeLev said in generalize a c++ method:

                  uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex", MachineBackend::nIndexUpdated);

                  uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex", &MachineBackend::nIndexUpdated);
                  
                  ODБOïO Offline
                  ODБOïO Offline
                  ODБOï
                  wrote on last edited by
                  #24

                  @jsulm yes sorry that is the first one i have tryed:

                  uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex", &MachineBackend::nIndexUpdated);
                  
                  // err :  cannot initialize a parameter of type 'Machinebackend::MethorPtr' (aka 'void (MAchinebackend::*)()') with an rvalue of type 'void (MAchineBAckend::*)(QOpcUa::NodeAttribute, const QVariant &)' : different number of parameters (0 vs 2)
                  
                  error : no matching function for call to 'MachineBackend::uaSub2(QScopedPointer<QOpcUaNode>&, const char [19], <unresolved overloaded function type>)'
                           uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex",MachineBackend::nIndexUpdated);
                                                                                               ^
                  
                  jsulmJ 2 Replies Last reply
                  0
                  • ODБOïO ODБOï

                    @jsulm yes sorry that is the first one i have tryed:

                    uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex", &MachineBackend::nIndexUpdated);
                    
                    // err :  cannot initialize a parameter of type 'Machinebackend::MethorPtr' (aka 'void (MAchinebackend::*)()') with an rvalue of type 'void (MAchineBAckend::*)(QOpcUa::NodeAttribute, const QVariant &)' : different number of parameters (0 vs 2)
                    
                    error : no matching function for call to 'MachineBackend::uaSub2(QScopedPointer<QOpcUaNode>&, const char [19], <unresolved overloaded function type>)'
                             uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex",MachineBackend::nIndexUpdated);
                                                                                                 ^
                    
                    jsulmJ Offline
                    jsulmJ Offline
                    jsulm
                    Lifetime Qt Champion
                    wrote on last edited by
                    #25
                    This post is deleted!
                    ODБOïO 1 Reply Last reply
                    0
                    • ODБOïO ODБOï

                      @jsulm yes sorry that is the first one i have tryed:

                      uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex", &MachineBackend::nIndexUpdated);
                      
                      // err :  cannot initialize a parameter of type 'Machinebackend::MethorPtr' (aka 'void (MAchinebackend::*)()') with an rvalue of type 'void (MAchineBAckend::*)(QOpcUa::NodeAttribute, const QVariant &)' : different number of parameters (0 vs 2)
                      
                      error : no matching function for call to 'MachineBackend::uaSub2(QScopedPointer<QOpcUaNode>&, const char [19], <unresolved overloaded function type>)'
                               uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex",MachineBackend::nIndexUpdated);
                                                                                                   ^
                      
                      jsulmJ Offline
                      jsulmJ Offline
                      jsulm
                      Lifetime Qt Champion
                      wrote on last edited by jsulm
                      #26

                      @LeLev said in generalize a c++ method:

                      nIndexUpdated

                      This one has parameters, you need to adapt your typedef for the pointer accordingly.
                      This is what the error tells you.

                      1 Reply Last reply
                      1
                      • jsulmJ jsulm

                        This post is deleted!

                        ODБOïO Offline
                        ODБOïO Offline
                        ODБOï
                        wrote on last edited by
                        #27

                        @jsulm

                        class MachineBackend : public QObject
                        {
                            typedef void (MachineBackend::*MethodPtr) ();
                            Q_OBJECT
                        
                        void nIndexUpdated(QOpcUa::NodeAttribute attr, const QVariant &value){...}
                        
                        void uaSub2(QScopedPointer<QOpcUaNode>&node, QString nodeId, MethodPtr updateHandlerPtr){
                               
                               (this->*updateHandlerPtr)();
                        
                            }
                        };
                        

                        in the constructor of this class i call m_client.connectToServer(), then connect stateChanged signal of the m_client to a method where i want to create the subscriptions :

                         QObject::connect(m_client.data(), &QOpcUaClient::stateChanged, this, &MachineBackend::clientStateHandler);
                        
                        void MachineBackend::clientStateHandler(QOpcUaClient::ClientState state)
                        {
                            setConnected((state == QOpcUaClient::ClientState::Connected)); 
                        
                            if (state == QOpcUaClient::ClientState::Connected) {// if client is connected i create subscriptions
                                         
                                // uaSub(nIndexNode,"ns=4;s=MAIN.nIndex",*nIndexUpdated); // function pointer to static function
                        
                                // uaSub1(nIndexNode,"ns=4;s=MAIN.nIndex", MachineBackend::NINDEX) // enum
                                
                                 uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex",&MachineBackend::nIndexUpdated);   
                        
                            }
                        
                           [...]
                        }
                        
                        

                        I think i have to adapt my typedef because &QOpcUaClient::stateChanged returns 2 parameters

                        jsulmJ 1 Reply Last reply
                        0
                        • ODБOïO ODБOï

                          @jsulm

                          class MachineBackend : public QObject
                          {
                              typedef void (MachineBackend::*MethodPtr) ();
                              Q_OBJECT
                          
                          void nIndexUpdated(QOpcUa::NodeAttribute attr, const QVariant &value){...}
                          
                          void uaSub2(QScopedPointer<QOpcUaNode>&node, QString nodeId, MethodPtr updateHandlerPtr){
                                 
                                 (this->*updateHandlerPtr)();
                          
                              }
                          };
                          

                          in the constructor of this class i call m_client.connectToServer(), then connect stateChanged signal of the m_client to a method where i want to create the subscriptions :

                           QObject::connect(m_client.data(), &QOpcUaClient::stateChanged, this, &MachineBackend::clientStateHandler);
                          
                          void MachineBackend::clientStateHandler(QOpcUaClient::ClientState state)
                          {
                              setConnected((state == QOpcUaClient::ClientState::Connected)); 
                          
                              if (state == QOpcUaClient::ClientState::Connected) {// if client is connected i create subscriptions
                                           
                                  // uaSub(nIndexNode,"ns=4;s=MAIN.nIndex",*nIndexUpdated); // function pointer to static function
                          
                                  // uaSub1(nIndexNode,"ns=4;s=MAIN.nIndex", MachineBackend::NINDEX) // enum
                                  
                                   uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex",&MachineBackend::nIndexUpdated);   
                          
                              }
                          
                             [...]
                          }
                          
                          

                          I think i have to adapt my typedef because &QOpcUaClient::stateChanged returns 2 parameters

                          jsulmJ Offline
                          jsulmJ Offline
                          jsulm
                          Lifetime Qt Champion
                          wrote on last edited by jsulm
                          #28

                          @LeLev said in generalize a c++ method:

                          I think i have to adapt my typedef

                          Yes, you have to specify the parameter types when defining a function/method pointer type.

                          1 Reply Last reply
                          3
                          • ODБOïO Offline
                            ODБOïO Offline
                            ODБOï
                            wrote on last edited by
                            #29

                            i'm having troubles to adapt the typedef..
                            should it be

                            typedef void (MachineBackend::*MethodPtr) (QOpcUa::NodeAttribute attr,const QVariant &value);
                            
                             or 
                            
                            typedef void (MachineBackend::*MethodPtr(QOpcUa::NodeAttribute attr,const QVariant &value)) ();
                            
                            jsulmJ 1 Reply Last reply
                            0
                            • ODБOïO ODБOï

                              i'm having troubles to adapt the typedef..
                              should it be

                              typedef void (MachineBackend::*MethodPtr) (QOpcUa::NodeAttribute attr,const QVariant &value);
                              
                               or 
                              
                              typedef void (MachineBackend::*MethodPtr(QOpcUa::NodeAttribute attr,const QVariant &value)) ();
                              
                              jsulmJ Offline
                              jsulmJ Offline
                              jsulm
                              Lifetime Qt Champion
                              wrote on last edited by
                              #30

                              @LeLev said in generalize a c++ method:

                              typedef void (MachineBackend::*MethodPtr) (QOpcUa::NodeAttribute attr,const QVariant &value);

                              typedef void (MachineBackend::*MethodPtr) (QOpcUa::NodeAttribute, const QVariant&);
                              

                              No need for parameter names, only types.

                              ODБOïO 1 Reply Last reply
                              3
                              • jsulmJ jsulm

                                @LeLev said in generalize a c++ method:

                                typedef void (MachineBackend::*MethodPtr) (QOpcUa::NodeAttribute attr,const QVariant &value);

                                typedef void (MachineBackend::*MethodPtr) (QOpcUa::NodeAttribute, const QVariant&);
                                

                                No need for parameter names, only types.

                                ODБOïO Offline
                                ODБOïO Offline
                                ODБOï
                                wrote on last edited by ODБOï
                                #31

                                @jsulm

                                class MachineBackend : public QObject
                                {
                                    typedef void (MachineBackend::*MethodPtr) (QOpcUa::NodeAttribute, const QVariant&);
                                
                                    Q_OBJECT
                                
                                public:
                                    void uaSub2(QScopedPointer<QOpcUaNode>&node, QString nodeId, MethodPtr updateHandlerPtr){
                                 
                                      //  trying to use lambda to call my pointed function but can't
                                
                                      /*  QObject::connect(node.data(),&QOpcUaNode::attributeUpdated,[&]{
                                             (this->*updateHandlerPtr() ) ();
                                        });
                                     */ 
                                  
                                         // maybe  is it possible to connect to my function directly  ?     
                                     QObject::connect(node.data(),&QOpcUaNode::attributeUpdated,this,&MachineBackend:: ??)
                                
                                    }
                                    
                                
                                };
                                
                                jsulmJ 1 Reply Last reply
                                0
                                • ODБOïO ODБOï

                                  @jsulm

                                  class MachineBackend : public QObject
                                  {
                                      typedef void (MachineBackend::*MethodPtr) (QOpcUa::NodeAttribute, const QVariant&);
                                  
                                      Q_OBJECT
                                  
                                  public:
                                      void uaSub2(QScopedPointer<QOpcUaNode>&node, QString nodeId, MethodPtr updateHandlerPtr){
                                   
                                        //  trying to use lambda to call my pointed function but can't
                                  
                                        /*  QObject::connect(node.data(),&QOpcUaNode::attributeUpdated,[&]{
                                               (this->*updateHandlerPtr() ) ();
                                          });
                                       */ 
                                    
                                           // maybe  is it possible to connect to my function directly  ?     
                                       QObject::connect(node.data(),&QOpcUaNode::attributeUpdated,this,&MachineBackend:: ??)
                                  
                                      }
                                      
                                  
                                  };
                                  
                                  jsulmJ Offline
                                  jsulmJ Offline
                                  jsulm
                                  Lifetime Qt Champion
                                  wrote on last edited by
                                  #32

                                  @LeLev said in generalize a c++ method:

                                  (this->*updateHandlerPtr() ) ();

                                  (this->*updateHandlerPtr) (); <--- You have to pass 2 parameters to it!
                                  
                                  ODБOïO 1 Reply Last reply
                                  3
                                  • jsulmJ jsulm

                                    @LeLev said in generalize a c++ method:

                                    (this->*updateHandlerPtr() ) ();

                                    (this->*updateHandlerPtr) (); <--- You have to pass 2 parameters to it!
                                    
                                    ODБOïO Offline
                                    ODБOïO Offline
                                    ODБOï
                                    wrote on last edited by ODБOï
                                    #33

                                    @jsulm yes but i don't have any parameter to pass to it .. .

                                    its just a handler function that must be connected to
                                    QOpcUaNode::attributeUpdated witch returns 2 values ;

                                    that is why it has to have 2 params.

                                    I don't want to call that function, i want it to be connected to

                                    QOpcUaNode::attributeUpdated , and called automatically when attributeUpdated is emitted in the opcua backend

                                    1 Reply Last reply
                                    0
                                    • ODБOïO Offline
                                      ODБOïO Offline
                                      ODБOï
                                      wrote on last edited by ODБOï
                                      #34

                                      @jsulm finally it is this working thanks to you !

                                      class MachineBackend : public QObject
                                      {
                                          typedef void (MachineBackend::*MethodPtr) (QOpcUa::NodeAttribute, const QVariant&);
                                      
                                          Q_OBJECT
                                      
                                      
                                      public:
                                      
                                      
                                          void uaSub2(QScopedPointer<QOpcUaNode>&node, QString nodeId, MethodPtr updateHandlerPtr){
                                      
                                           QObject::connect(node.data(),&QOpcUaNode::attributeUpdated,this,updateHandlerPtr);
                                      
                                          }
                                      
                                        void nIndexUpdated(QOpcUa::NodeAttribute attr, const QVariant &value){
                                              //return; // i can access member variables / signal / methods here
                                          }
                                      
                                      
                                      // use uaSub
                                      
                                      uaSub2(nIndexNode,"ns=4;s=MAIN.nIndex",&MachineBackend::nIndexUpdated);
                                      //
                                      
                                      };
                                      

                                      thank you infinitely everybody who helped me

                                      1 Reply Last reply
                                      2

                                      • Login

                                      • Login or register to search.
                                      • First post
                                        Last post
                                      0
                                      • Categories
                                      • Recent
                                      • Tags
                                      • Popular
                                      • Users
                                      • Groups
                                      • Search
                                      • Get Qt Extensions
                                      • Unsolved