打包并将可变模板参数传递给另一个模板类

问题描述 投票:0回答:1

这个代码片段实现了两个类——一个接受命令名称和支持的子命令列表的命令处理程序,以及一个包含所有此类支持的“命令”的元类。

我正在寻找一种方法来一起初始化这些顶级

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;
}

c++ templates c++17 variadic-templates
1个回答
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
© www.soinside.com 2019 - 2024. All rights reserved.