我想创建一个可重用的类,该类描述一个结构数组,其中包含一个指向类中方法的指针。该类还包含“执行”和“显示”方法。我认为execute方法也需要模板化,但是我仍在努力学习模板。
挑战:如何将此类转化为模板并提供 几个使用模板的例子?
该类结合了typedef
,struct
和我想在多个类之间共享的方法。每个实例将具有自己的struct
数组,每个数组都包含一个指向字符串的指针和一个指向类中方法的指针。
我想使用模板,以便它支持同一struct
的数组的多个实例,但是内容不同。
此代码表示的是一种实现简单命令语言的方法,该方法将两个代码(sel和act)传递给execute方法,该方法在数组中搜索两个代码的匹配项,然后分派相应的方法。
此代码还包括模板中也需要包含的两种方法:show
(遍历数组并为每个命令提供帮助信息)和execute
(调用适当的函数)。
class Commands {
public:
typedef void ( Commands::*FunctionPointer )( char, char );
struct command {
char sel;
char act;
char const *desc;
FunctionPointer funcPtr;
};
command myCommands [2] = {
command { 'a','?',"Pass a and ? to foo", &Commands::foo },
command { 'b','x',"Pass b and x to bar", &Commands::bar },
};
int cmdSize = sizeof ( myCommands ) / sizeof ( myCommands [0] );
void foo ( char sel, char act ) {
show ( { sel }, { act } );
}
void bar ( char sel, char act ) {
show ( { sel }, { act } );
}
void show ( char sel, char act ) {
// sel and act are ignored vy this method
for (int i = 0; i < cmdSize; i++) {
Serial.print ( "SEL = " );
Serial.print ( myCommands [i].sel );
if (sel == myCommands [i].sel) Serial.print ( '*' );
Serial.print ( ", ACT=" );
Serial.print ( myCommands [i].act );
if (act == myCommands [i].act) Serial.print ( '*' );
Serial.print ( ' ' );
Serial.println ( myCommands [i].desc );
}
}
void execute ( char sel, char act ) {
for (int i = 0; i < cmdSize; i++) {
if (myCommands [i].sel == sel && myCommands [i].act == act) {
Serial.println ( myCommands [i].desc );
( this->*myCommands [i].funcPtr )( sel, act );
return;
}
}
Serial.print ( F ( "Unknown SEL/ACT Pair:" ) );
Serial.print ( sel );
Serial.print ( '/' );
Serial.println ( act );
}
};
还有Arduino Sketch:
#include "Commands.h"
Commands cmd;
void setup() {
Serial.begin ( 115200 );
cmd.show ( '?', '?' );
Serial.println ( "EXECUTING:" );
cmd.execute ( 'a', '?' );
cmd.execute ( 'b', '?' );
cmd.execute ( 'b', 'x' );
Serial.println ( "DONE" );
}
void loop(){}
最后,是执行草图的输出:
SEL = a, ACT=?* Pass a and ? to foo
SEL = b, ACT=x Pass b and x to bar
EXECUTING:
Pass a and ? to foo
SEL = a*, ACT=?* Pass a and ? to foo
SEL = b, ACT=x Pass b and x to bar
Unknown SEL/ACT Pair:b/?
Pass b and x to bar
SEL = a, ACT=? Pass a and ? to foo
SEL = b*, ACT=x* Pass b and x to bar
DONE
答案 0 :(得分:0)
我想创建一个可重用的类来描述结构数组 其中包含指向类中方法的指针。上课还 包含“执行”和“显示”方法。我认为执行方法 也需要模板化,但我仍在努力学习 模板。
我不得不说我不明白你想确切地做什么。但是,查看您的代码似乎要使用std::map
而不是数组(因此您可以将“命令”映射到函数指针)。如果要调用的所有方法都具有相同的签名(void(char,char)
),则无需过多处理模板。相反,我建议您看看std::function
和lambda。
#include <iostream>
#include <string>
#include <map>
struct command_center {
using command = std::string;
using comment = std::string;
using action = std::function< void(char,char) >;
std::map< command,action > action_commands;
void register_action_command( command c, action a) {
action_commands[c] = a;
}
void execute( command c, char a,char b) {
auto it = action_commands.find(c);
if (it == action_commands.end()) {
std::cout << "command not found: " << c << "\n";
return;
}
it->second(a,b);
}
};
struct foo{
void bar(char a,char b) { std::cout << a << b << " foo\n";}
};
int main(){
command_center cc;
cc.register_action_command("test1",[](char a,char b){ std::cout << a << b << "\n";});
cc.execute("test1",'a','b');
cc.execute("unknown",'a','b');
foo f;
cc.register_action_command("foobar",[&f](char a,char b){ f.bar(a,b); });
cc.execute("foobar",'a','b');
}
输出:
ab
command not found: unknown
ab foo
请注意,当您将自己限制为固定签名(即类型的函数指针)时,它可以在没有lamdbas和std::function
的情况下工作
using my_function_pointer_type = void(*)(char,char);
但是,通过将lambda传递给std::function
,您可以包装带有正确签名的任何可调用对象,并将其注册以供以后调用(无论它是自由函数还是示例中的某些成员方法)。
PS:可以对上面的command_center
进行参数设置,以使用具有不同签名的函数指针。只是在写完这个答案后,我才意识到问题可能就是这个问题吗?