Calling a method with an array of pointers to class::method
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
add a comment |
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
add a comment |
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
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
c++ templates arduino typedef
edited Nov 20 '18 at 7:55
Bob Jones
asked Nov 20 '18 at 3:22
Bob JonesBob Jones
1,08152452
1,08152452
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
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');
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 '18 at 6:42
@BobJones For example you can't usesel
andact
fromvoid(T::*func)(char sel, char act)
. How would you even pass it? The only variable you have is thefunc
. Another error is about passing too many arguments to the dispatch (maybe related with previous).
– KIIV
Nov 20 '18 at 11:18
add a comment |
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',
autoActivateHeartbeat: false,
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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');
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 '18 at 6:42
@BobJones For example you can't usesel
andact
fromvoid(T::*func)(char sel, char act)
. How would you even pass it? The only variable you have is thefunc
. Another error is about passing too many arguments to the dispatch (maybe related with previous).
– KIIV
Nov 20 '18 at 11:18
add a comment |
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');
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 '18 at 6:42
@BobJones For example you can't usesel
andact
fromvoid(T::*func)(char sel, char act)
. How would you even pass it? The only variable you have is thefunc
. Another error is about passing too many arguments to the dispatch (maybe related with previous).
– KIIV
Nov 20 '18 at 11:18
add a comment |
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');
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');
answered Nov 20 '18 at 3:47
AIMIN PANAIMIN PAN
20528
20528
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 '18 at 6:42
@BobJones For example you can't usesel
andact
fromvoid(T::*func)(char sel, char act)
. How would you even pass it? The only variable you have is thefunc
. Another error is about passing too many arguments to the dispatch (maybe related with previous).
– KIIV
Nov 20 '18 at 11:18
add a comment |
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 '18 at 6:42
@BobJones For example you can't usesel
andact
fromvoid(T::*func)(char sel, char act)
. How would you even pass it? The only variable you have is thefunc
. Another error is about passing too many arguments to the dispatch (maybe related with previous).
– KIIV
Nov 20 '18 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 '18 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 '18 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 '18 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 '18 at 11:18
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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