Calling a method with an array of pointers to class::method











up vote
0
down vote

favorite












I want to call a method that will accept as an argument a pointer to a list of class:method pointers:



void dispatch ( int cmdCount, methodFunction *pointer  ) {
...
}


This typedef creates methodFunction:



typedef void ( ClassName::*methodFunction )( char, char );


But I cannot see how to make ClassName something that gets passed to dispatch. I think this needs some form of template, but I am not clear on templates yet.



Here is my entire code (drop code into TemplateTest.ino and code.h:



    //  Template Test
#include "code.h"

Dispatcher *dispatcher;
Example1 ex1;
Example2 ex2;

void setup() {
Serial.begin ( 115200 );

ex1.execute ( 'a', '+' );
ex1.execute ( 'b', '-' );
ex2.execute ( 'y', '?' );
}

void loop() {}

<<<<<<<<<< NEW FILE: code.h >>>>>>>>>>>>

#pragma once

class Dispatcher {
public:
template<class T>

void dispatch ( T& instance, void(T::*func)(char sel, char act), char def [2], int cmdCount ) {
// Walk through the array containing sel,act pairs.
// When we find a match, launch the function from
// tPointer with the same index value.
for (int i = 0; i < cmdCount; i++) {
char _sel = def [i] [0];
char _act = def [i] [1];
if (( sel == _sel ) && ( act == _act )) {
( *T [i] )( sel, act );
return;
}
}
}
};

// Example 1 Code
char ex1Array [2] = {
{'a','+'},
{'a','-'},
{'b','+'},
{'b','-'},
};

class Example1 {
public:

char *_name = "Template Example 1";

Dispatcher disp;

static const int cmdCount = sizeof ( ex1Array ) / sizeof ( ex1Array [0] );

typedef void ( Example1::*FunctionPointer )( char sel, char act );

// Function dispatch table
FunctionPointer cmdMethods [cmdCount] = {
&Example1::alphaPlus,
&Example1::alphaMinus,
&Example1::betaPlus,
&Example1::betaMinus,
};

Example1 () {
}

void alphaPlus ( char sel, char act ) {
Serial.println ( F ( "Alpha +" ) );
}
void alphaMinus ( char sel, char act ) {
Serial.println ( F ( "Alpha -" ) );
}
void betaPlus ( char sel, char act ) {
Serial.println ( F ( "Beta +" ) );
}
void betaMinus ( char sel, char act ) {
Serial.println ( F ( "Beta -" ) );
}

void execute ( char sel, char act ) {
disp.dispatch ( *this, cmdMethods [0], 'a', 'b', ex1Array[0], cmdCount );
}

};

// Example 2
char ex2Array [2] = {
{'x','?'},
{'y','?'},
{'z','?'},
};

class Example2 {
public:

char *_name = "Template Example 2";

Dispatcher disp;

static const int cmdCount = sizeof ( ex2Array ) / sizeof ( ex2Array [0] );

typedef void ( Example2::*FunctionPointer )( char sel, char act );

// Function dispatch table
FunctionPointer cmdMethods [cmdCount] = {
&Example2::x,
&Example2::y,
&Example2::z,
};

Example2 () {
}

void x ( char sel, char act ) {
Serial.println ( F ( "X" ) );
}
void y ( char sel, char act ) {
Serial.println ( F ( "Y" ) );
}
void z ( char sel, char act ) {
Serial.println ( F ( "Z" ) );
}

void execute ( char sel, char act ) {
disp.dispatch ( *this, cmdMethods [0], 'a', 'b', ex2Array [0], cmdCount );
}
};









share|improve this question




























    up vote
    0
    down vote

    favorite












    I want to call a method that will accept as an argument a pointer to a list of class:method pointers:



    void dispatch ( int cmdCount, methodFunction *pointer  ) {
    ...
    }


    This typedef creates methodFunction:



    typedef void ( ClassName::*methodFunction )( char, char );


    But I cannot see how to make ClassName something that gets passed to dispatch. I think this needs some form of template, but I am not clear on templates yet.



    Here is my entire code (drop code into TemplateTest.ino and code.h:



        //  Template Test
    #include "code.h"

    Dispatcher *dispatcher;
    Example1 ex1;
    Example2 ex2;

    void setup() {
    Serial.begin ( 115200 );

    ex1.execute ( 'a', '+' );
    ex1.execute ( 'b', '-' );
    ex2.execute ( 'y', '?' );
    }

    void loop() {}

    <<<<<<<<<< NEW FILE: code.h >>>>>>>>>>>>

    #pragma once

    class Dispatcher {
    public:
    template<class T>

    void dispatch ( T& instance, void(T::*func)(char sel, char act), char def [2], int cmdCount ) {
    // Walk through the array containing sel,act pairs.
    // When we find a match, launch the function from
    // tPointer with the same index value.
    for (int i = 0; i < cmdCount; i++) {
    char _sel = def [i] [0];
    char _act = def [i] [1];
    if (( sel == _sel ) && ( act == _act )) {
    ( *T [i] )( sel, act );
    return;
    }
    }
    }
    };

    // Example 1 Code
    char ex1Array [2] = {
    {'a','+'},
    {'a','-'},
    {'b','+'},
    {'b','-'},
    };

    class Example1 {
    public:

    char *_name = "Template Example 1";

    Dispatcher disp;

    static const int cmdCount = sizeof ( ex1Array ) / sizeof ( ex1Array [0] );

    typedef void ( Example1::*FunctionPointer )( char sel, char act );

    // Function dispatch table
    FunctionPointer cmdMethods [cmdCount] = {
    &Example1::alphaPlus,
    &Example1::alphaMinus,
    &Example1::betaPlus,
    &Example1::betaMinus,
    };

    Example1 () {
    }

    void alphaPlus ( char sel, char act ) {
    Serial.println ( F ( "Alpha +" ) );
    }
    void alphaMinus ( char sel, char act ) {
    Serial.println ( F ( "Alpha -" ) );
    }
    void betaPlus ( char sel, char act ) {
    Serial.println ( F ( "Beta +" ) );
    }
    void betaMinus ( char sel, char act ) {
    Serial.println ( F ( "Beta -" ) );
    }

    void execute ( char sel, char act ) {
    disp.dispatch ( *this, cmdMethods [0], 'a', 'b', ex1Array[0], cmdCount );
    }

    };

    // Example 2
    char ex2Array [2] = {
    {'x','?'},
    {'y','?'},
    {'z','?'},
    };

    class Example2 {
    public:

    char *_name = "Template Example 2";

    Dispatcher disp;

    static const int cmdCount = sizeof ( ex2Array ) / sizeof ( ex2Array [0] );

    typedef void ( Example2::*FunctionPointer )( char sel, char act );

    // Function dispatch table
    FunctionPointer cmdMethods [cmdCount] = {
    &Example2::x,
    &Example2::y,
    &Example2::z,
    };

    Example2 () {
    }

    void x ( char sel, char act ) {
    Serial.println ( F ( "X" ) );
    }
    void y ( char sel, char act ) {
    Serial.println ( F ( "Y" ) );
    }
    void z ( char sel, char act ) {
    Serial.println ( F ( "Z" ) );
    }

    void execute ( char sel, char act ) {
    disp.dispatch ( *this, cmdMethods [0], 'a', 'b', ex2Array [0], cmdCount );
    }
    };









    share|improve this question


























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I want to call a method that will accept as an argument a pointer to a list of class:method pointers:



      void dispatch ( int cmdCount, methodFunction *pointer  ) {
      ...
      }


      This typedef creates methodFunction:



      typedef void ( ClassName::*methodFunction )( char, char );


      But I cannot see how to make ClassName something that gets passed to dispatch. I think this needs some form of template, but I am not clear on templates yet.



      Here is my entire code (drop code into TemplateTest.ino and code.h:



          //  Template Test
      #include "code.h"

      Dispatcher *dispatcher;
      Example1 ex1;
      Example2 ex2;

      void setup() {
      Serial.begin ( 115200 );

      ex1.execute ( 'a', '+' );
      ex1.execute ( 'b', '-' );
      ex2.execute ( 'y', '?' );
      }

      void loop() {}

      <<<<<<<<<< NEW FILE: code.h >>>>>>>>>>>>

      #pragma once

      class Dispatcher {
      public:
      template<class T>

      void dispatch ( T& instance, void(T::*func)(char sel, char act), char def [2], int cmdCount ) {
      // Walk through the array containing sel,act pairs.
      // When we find a match, launch the function from
      // tPointer with the same index value.
      for (int i = 0; i < cmdCount; i++) {
      char _sel = def [i] [0];
      char _act = def [i] [1];
      if (( sel == _sel ) && ( act == _act )) {
      ( *T [i] )( sel, act );
      return;
      }
      }
      }
      };

      // Example 1 Code
      char ex1Array [2] = {
      {'a','+'},
      {'a','-'},
      {'b','+'},
      {'b','-'},
      };

      class Example1 {
      public:

      char *_name = "Template Example 1";

      Dispatcher disp;

      static const int cmdCount = sizeof ( ex1Array ) / sizeof ( ex1Array [0] );

      typedef void ( Example1::*FunctionPointer )( char sel, char act );

      // Function dispatch table
      FunctionPointer cmdMethods [cmdCount] = {
      &Example1::alphaPlus,
      &Example1::alphaMinus,
      &Example1::betaPlus,
      &Example1::betaMinus,
      };

      Example1 () {
      }

      void alphaPlus ( char sel, char act ) {
      Serial.println ( F ( "Alpha +" ) );
      }
      void alphaMinus ( char sel, char act ) {
      Serial.println ( F ( "Alpha -" ) );
      }
      void betaPlus ( char sel, char act ) {
      Serial.println ( F ( "Beta +" ) );
      }
      void betaMinus ( char sel, char act ) {
      Serial.println ( F ( "Beta -" ) );
      }

      void execute ( char sel, char act ) {
      disp.dispatch ( *this, cmdMethods [0], 'a', 'b', ex1Array[0], cmdCount );
      }

      };

      // Example 2
      char ex2Array [2] = {
      {'x','?'},
      {'y','?'},
      {'z','?'},
      };

      class Example2 {
      public:

      char *_name = "Template Example 2";

      Dispatcher disp;

      static const int cmdCount = sizeof ( ex2Array ) / sizeof ( ex2Array [0] );

      typedef void ( Example2::*FunctionPointer )( char sel, char act );

      // Function dispatch table
      FunctionPointer cmdMethods [cmdCount] = {
      &Example2::x,
      &Example2::y,
      &Example2::z,
      };

      Example2 () {
      }

      void x ( char sel, char act ) {
      Serial.println ( F ( "X" ) );
      }
      void y ( char sel, char act ) {
      Serial.println ( F ( "Y" ) );
      }
      void z ( char sel, char act ) {
      Serial.println ( F ( "Z" ) );
      }

      void execute ( char sel, char act ) {
      disp.dispatch ( *this, cmdMethods [0], 'a', 'b', ex2Array [0], cmdCount );
      }
      };









      share|improve this question















      I want to call a method that will accept as an argument a pointer to a list of class:method pointers:



      void dispatch ( int cmdCount, methodFunction *pointer  ) {
      ...
      }


      This typedef creates methodFunction:



      typedef void ( ClassName::*methodFunction )( char, char );


      But I cannot see how to make ClassName something that gets passed to dispatch. I think this needs some form of template, but I am not clear on templates yet.



      Here is my entire code (drop code into TemplateTest.ino and code.h:



          //  Template Test
      #include "code.h"

      Dispatcher *dispatcher;
      Example1 ex1;
      Example2 ex2;

      void setup() {
      Serial.begin ( 115200 );

      ex1.execute ( 'a', '+' );
      ex1.execute ( 'b', '-' );
      ex2.execute ( 'y', '?' );
      }

      void loop() {}

      <<<<<<<<<< NEW FILE: code.h >>>>>>>>>>>>

      #pragma once

      class Dispatcher {
      public:
      template<class T>

      void dispatch ( T& instance, void(T::*func)(char sel, char act), char def [2], int cmdCount ) {
      // Walk through the array containing sel,act pairs.
      // When we find a match, launch the function from
      // tPointer with the same index value.
      for (int i = 0; i < cmdCount; i++) {
      char _sel = def [i] [0];
      char _act = def [i] [1];
      if (( sel == _sel ) && ( act == _act )) {
      ( *T [i] )( sel, act );
      return;
      }
      }
      }
      };

      // Example 1 Code
      char ex1Array [2] = {
      {'a','+'},
      {'a','-'},
      {'b','+'},
      {'b','-'},
      };

      class Example1 {
      public:

      char *_name = "Template Example 1";

      Dispatcher disp;

      static const int cmdCount = sizeof ( ex1Array ) / sizeof ( ex1Array [0] );

      typedef void ( Example1::*FunctionPointer )( char sel, char act );

      // Function dispatch table
      FunctionPointer cmdMethods [cmdCount] = {
      &Example1::alphaPlus,
      &Example1::alphaMinus,
      &Example1::betaPlus,
      &Example1::betaMinus,
      };

      Example1 () {
      }

      void alphaPlus ( char sel, char act ) {
      Serial.println ( F ( "Alpha +" ) );
      }
      void alphaMinus ( char sel, char act ) {
      Serial.println ( F ( "Alpha -" ) );
      }
      void betaPlus ( char sel, char act ) {
      Serial.println ( F ( "Beta +" ) );
      }
      void betaMinus ( char sel, char act ) {
      Serial.println ( F ( "Beta -" ) );
      }

      void execute ( char sel, char act ) {
      disp.dispatch ( *this, cmdMethods [0], 'a', 'b', ex1Array[0], cmdCount );
      }

      };

      // Example 2
      char ex2Array [2] = {
      {'x','?'},
      {'y','?'},
      {'z','?'},
      };

      class Example2 {
      public:

      char *_name = "Template Example 2";

      Dispatcher disp;

      static const int cmdCount = sizeof ( ex2Array ) / sizeof ( ex2Array [0] );

      typedef void ( Example2::*FunctionPointer )( char sel, char act );

      // Function dispatch table
      FunctionPointer cmdMethods [cmdCount] = {
      &Example2::x,
      &Example2::y,
      &Example2::z,
      };

      Example2 () {
      }

      void x ( char sel, char act ) {
      Serial.println ( F ( "X" ) );
      }
      void y ( char sel, char act ) {
      Serial.println ( F ( "Y" ) );
      }
      void z ( char sel, char act ) {
      Serial.println ( F ( "Z" ) );
      }

      void execute ( char sel, char act ) {
      disp.dispatch ( *this, cmdMethods [0], 'a', 'b', ex2Array [0], cmdCount );
      }
      };






      c++ templates arduino typedef






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 20 at 7:55

























      asked Nov 20 at 3:22









      Bob Jones

      1,07652452




      1,07652452
























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          0
          down vote













          dispatch should called with an instance.



          template<class T>
          void dispatch(T& instance, void(T::*func)(char, char), char param1, char param2 )
          {
          instance.*func(param1, param2);
          }


          call dispatch:



          dispatch(*this, cmdMethods[0], 'a', 'b');





          share|improve this answer





















          • Thanks, AIMIN PAN. Your input helped. I have updated the posted code with your suggestions but there are still five compile errors.
            – Bob Jones
            Nov 20 at 6:42










          • @BobJones For example you can't use sel and act from void(T::*func)(char sel, char act). How would you even pass it? The only variable you have is the func. Another error is about passing too many arguments to the dispatch (maybe related with previous).
            – KIIV
            Nov 20 at 11:18











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53385750%2fcalling-a-method-with-an-array-of-pointers-to-classmethod%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          0
          down vote













          dispatch should called with an instance.



          template<class T>
          void dispatch(T& instance, void(T::*func)(char, char), char param1, char param2 )
          {
          instance.*func(param1, param2);
          }


          call dispatch:



          dispatch(*this, cmdMethods[0], 'a', 'b');





          share|improve this answer





















          • Thanks, AIMIN PAN. Your input helped. I have updated the posted code with your suggestions but there are still five compile errors.
            – Bob Jones
            Nov 20 at 6:42










          • @BobJones For example you can't use sel and act from void(T::*func)(char sel, char act). How would you even pass it? The only variable you have is the func. Another error is about passing too many arguments to the dispatch (maybe related with previous).
            – KIIV
            Nov 20 at 11:18















          up vote
          0
          down vote













          dispatch should called with an instance.



          template<class T>
          void dispatch(T& instance, void(T::*func)(char, char), char param1, char param2 )
          {
          instance.*func(param1, param2);
          }


          call dispatch:



          dispatch(*this, cmdMethods[0], 'a', 'b');





          share|improve this answer





















          • Thanks, AIMIN PAN. Your input helped. I have updated the posted code with your suggestions but there are still five compile errors.
            – Bob Jones
            Nov 20 at 6:42










          • @BobJones For example you can't use sel and act from void(T::*func)(char sel, char act). How would you even pass it? The only variable you have is the func. Another error is about passing too many arguments to the dispatch (maybe related with previous).
            – KIIV
            Nov 20 at 11:18













          up vote
          0
          down vote










          up vote
          0
          down vote









          dispatch should called with an instance.



          template<class T>
          void dispatch(T& instance, void(T::*func)(char, char), char param1, char param2 )
          {
          instance.*func(param1, param2);
          }


          call dispatch:



          dispatch(*this, cmdMethods[0], 'a', 'b');





          share|improve this answer












          dispatch should called with an instance.



          template<class T>
          void dispatch(T& instance, void(T::*func)(char, char), char param1, char param2 )
          {
          instance.*func(param1, param2);
          }


          call dispatch:



          dispatch(*this, cmdMethods[0], 'a', 'b');






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 20 at 3:47









          AIMIN PAN

          20628




          20628












          • Thanks, AIMIN PAN. Your input helped. I have updated the posted code with your suggestions but there are still five compile errors.
            – Bob Jones
            Nov 20 at 6:42










          • @BobJones For example you can't use sel and act from void(T::*func)(char sel, char act). How would you even pass it? The only variable you have is the func. Another error is about passing too many arguments to the dispatch (maybe related with previous).
            – KIIV
            Nov 20 at 11:18


















          • Thanks, AIMIN PAN. Your input helped. I have updated the posted code with your suggestions but there are still five compile errors.
            – Bob Jones
            Nov 20 at 6:42










          • @BobJones For example you can't use sel and act from void(T::*func)(char sel, char act). How would you even pass it? The only variable you have is the func. Another error is about passing too many arguments to the dispatch (maybe related with previous).
            – KIIV
            Nov 20 at 11:18
















          Thanks, AIMIN PAN. Your input helped. I have updated the posted code with your suggestions but there are still five compile errors.
          – Bob Jones
          Nov 20 at 6:42




          Thanks, AIMIN PAN. Your input helped. I have updated the posted code with your suggestions but there are still five compile errors.
          – Bob Jones
          Nov 20 at 6:42












          @BobJones For example you can't use sel and act from void(T::*func)(char sel, char act). How would you even pass it? The only variable you have is the func. Another error is about passing too many arguments to the dispatch (maybe related with previous).
          – KIIV
          Nov 20 at 11:18




          @BobJones For example you can't use sel and act from void(T::*func)(char sel, char act). How would you even pass it? The only variable you have is the func. Another error is about passing too many arguments to the dispatch (maybe related with previous).
          – KIIV
          Nov 20 at 11:18


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53385750%2fcalling-a-method-with-an-array-of-pointers-to-classmethod%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Costa Masnaga

          Fotorealismo

          Sidney Franklin