如何动态组装类型列表以作为可变参数模板参数传递

时间:2019-06-21 02:01:29

标签: c++14 c++17

我有一个采用可变参数模板参数作为输入的函数。我真正需要做的是使用某种魔术容器(类型列表,元组等)来提供此功能参数。主要问题在于,该魔术容器需要在运行时根据先前函数调用的输入进行动态组装。

标准元组生成显然不能在这种环境下工作,因此我相信某种类型的包装器或帮助程序以及某种类型的名称修饰是有序的,但是这样做的方式使我难以理解。下面是我要尝试执行的一些示例伪代码。用户将多次调用AddComponent(),以将多个组件添加到拥有的管理器中。对于AddComponent()的每个实例,我需要将传入的“组件”类型存储到魔术容器中,以便最终得到一个包含所有已添加组件类型的容器。完成所有这些之后,我需要使用组合的类型名列表作为可变参数模板的参数来调用GetView()。元组最适合这里,但是如何正确组装呢?这是代码:

template<typename Component, typename ... Args>
void Blueprint::AddComponent(ComponentUsage usage, Args&& ... args)
{
// Create component object with given args

// Add 'Component' type to magic container
}

template<typename ... Component>
EntityView<Component...> EntityManager::GetView()
{
    // Create view from list of component types
}

1 个答案:

答案 0 :(得分:0)

您所描述的内容听起来很像builder pattern,并且可以使用以下语法获得相似行为:

// view would be EntityView<Location, Enemy, Flying> 
auto view = makeBlueprint()
              .AddComponent<Location>(...)
              .AddComponent<Enemy>(...)
              .AddComponent<Flying>(...)
              .GetView();

这将使用动态生成器,其中添加的每个组件都会创建一个稍微不同的生成器,例如Builder<>,然后.AddComponent<Location>()将返回Builder<Location>,然后返回Builder<Location, Enemy>,依此类推。

但是,这仍然不允许动态输入。像这样的东西行不通:

auto blueprint = makeBlueprint()
                   .AddComponent<Location>(...)
                   .AddComponent<Enemy>(...);

if (... some check ...)
    blueprint = blueprint.AddComponent<Flying>(...);

auto view = blueprint.GetView();

我怀疑这是否可以解决您的问题,因为必须仍然是动态输入并且不能“在运行时动态组装”。但我希望它能为您提供任何见识。