这个代码片段实现了两个类——一个接受命令名称和支持的子命令列表的命令处理程序,以及一个包含所有此类支持的“命令”的元类。
我正在寻找一种方法来一起初始化这些顶级
CommandHandler
对象(cmd_one_
,cmd_two_
),而不是初始化单个对象,这样说:
MetaCommandWrapper<COMMAND_ONE,
<cmd_one::SUBCMD_ONE,
cmd_one::SUBCMD_TWO
>,
COMMAND_TWO,
<cmd_two::SUBCMD_ONE,
cmd_two::SUBCMD_TWO
>
> meta_commands_;
这将使在
MetaCommands
中循环支持的命令并调用适当的CommandHandler
类的方法变得更容易。例如,一个方法 execute
发出如下: m.execute(COMMAND_ONE, cmd_one::SUBCMD_TWO)
将执行命令的第二个子命令,等等。
我该怎么做?
#include <cstdint>
enum meta_commands
{
COMMAND_ONE,
COMMAND_TWO
};
namespace cmd_one
{
enum subcmd
{
SUBCMD_ONE,
SUBCMD_TWO
};
}
namespace cmd_two
{
enum subcmd
{
SUBCMD_ONE,
SUBCMD_TWO
};
}
template <uint32_t Command, uint32_t...SubCommands>
class CommandHandler
{
};
class MetaCommands
{
private:
CommandHandler<meta_commands::COMMAND_ONE, cmd_one::SUBCMD_ONE, cmd_one::SUBCMD_TWO> cmd_one_;
CommandHandler<meta_commands::COMMAND_TWO, cmd_two::SUBCMD_ONE, cmd_two::SUBCMD_TWO> cmd_two_;
};
int main()
{
MetaCommands m;
return 0;
}
我不确定你到底需要什么,但看起来
MetaCommands
应该是一个类模板,因为你想用不同的模板参数创建它:
template <class... CmdHandlers>
class MetaCommands {};
这不会让你完全按照你的要求创建一个实例,但它会非常相似:
int main() {
MetaCommands<
CommandHandler<COMMAND_ONE, cmd_one::SUBCMD_ONE, cmd_one::SUBCMD_TWO>,
CommandHandler<COMMAND_TWO, cmd_two::SUBCMD_ONE, cmd_two::SUBCMD_TWO>
> meta_commands_;
}
然后您可以根据需要提取或折叠模板参数。假设您添加了一个函数来打印
Command
的
SubCommand
和
CommandHandler
s
template <uint32_t Command, uint32_t... SubCommands>
class CommandHandler {
friend std::ostream& operator<<(std::ostream& os, const CommandHandler&) {
os << "Cmd: " << Command << " Subs:";
(..., (os << ' ' << SubCommands));
return os;
}
};
并将其添加到
MetaCommands
:
template <class... CmdHandlers>
class MetaCommands {
private:
friend std::ostream& operator<<(std::ostream& os, const MetaCommands&) {
(..., (os << CmdHandlers{} << '\n'));
return os;
}
};
你可以像这样在
main
中打印它:
int main() {
MetaCommands<
CommandHandler<COMMAND_ONE, cmd_one::SUBCMD_ONE, cmd_one::SUBCMD_TWO>,
CommandHandler<COMMAND_TWO, cmd_two::SUBCMD_ONE, cmd_two::SUBCMD_TWO>
> meta_commands_;
std::cout << meta_commands_ << '\n';
}
输出:
Cmd: 0 Subs: 0 1
Cmd: 1 Subs: 0 1