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 12.9k 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 said in generalize a c++ method:

    i think i can not use this last solution

    Sure you can: you pass the pointer to second method when you call the first method, right? And since both methods are not static you call the first method already on an instance (which is "this" inside the method):

    this->*method(); // method is the pointer to the other method
    
    ODБOïO Offline
    ODБOïO Offline
    ODБOï
    wrote on last edited by ODБOï
    #15

    @jsulm said in generalize a c++ method:

    : you pass the pointer to second method when you call the first method, right?

    Yes, but it only works if the
    2nd method is static !

    //first 
    void uaSub(QScopedPointer<QOpcUaNode> &node, QString nodeId , void (*theUpdateHandler)(QOpcUa::NodeAttribute attr,const QVariant &value)){...}
    // 2nd
    static void nIndexUpdated(QOpcUa::NodeAttribute attr, const QVariant &value){...}
    
    
    uaSub(nIndexNode,"ns=4;s=MAIN.nIndex",*nIndexUpdated){...}
    
    //Here **nIndexUpdated** must be static !  no ?
    

    if it is not static i get :
    reference to non-static member function must be called error

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

      @jsulm said in generalize a c++ method:

      : you pass the pointer to second method when you call the first method, right?

      Yes, but it only works if the
      2nd method is static !

      //first 
      void uaSub(QScopedPointer<QOpcUaNode> &node, QString nodeId , void (*theUpdateHandler)(QOpcUa::NodeAttribute attr,const QVariant &value)){...}
      // 2nd
      static void nIndexUpdated(QOpcUa::NodeAttribute attr, const QVariant &value){...}
      
      
      uaSub(nIndexNode,"ns=4;s=MAIN.nIndex",*nIndexUpdated){...}
      
      //Here **nIndexUpdated** must be static !  no ?
      

      if it is not static i get :
      reference to non-static member function must be called error

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

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