简体   繁体   English

模板类的多变量参数包

[英]Multiple Variadic Parameter Pack for Template Class

I am using variadic parameter packs for policy based class design.我正在使用可变参数包进行基于策略的类设计。

template <APITypes APIType, class... Policies>
class IShader : public Policies... {

};

Policies are defined when called or with defaults if none are specified.策略是在调用时定义的,或者如果没有指定则使用默认值。 The problem comes when I need to add another variadic parameter pack:当我需要添加另一个可变参数包时出现问题:

template <AttributeType... Attributes, APITypes APIType, class... Policies>
class IShader : public Policies... {

};

This results in the error "Template parameter pack must be the last template parameter".这会导致错误“模板参数包必须是最后一个模板参数”。 I am planning to use the attribute pack to change the behaviour of at least one of the policies.我计划使用属性包来更改至少一项策略的行为。 But I can't work out how to get two variadic parameter packs in one template class.但是我不知道如何在一个模板类中获得两个可变参数包。

I think the simplest answer is to create template type wrappers for your parameter packs. 我认为最简单的答案是为参数包创建模板类型包装器。 For example: 例如:

template <AttributeType... T>
struct Attributes {};

template <typename... T>
struct Policies {};

Then you can declare your IShader type: 然后你可以声明你的IShader类型:

template <typename... T>
class IShader;

Create your implementation as a specialization. 将您的实现创建为专业化。 Note that in a specialization, you can have multiple parameter pack arguments. 请注意,在专门化中,您可以拥有多个参数包参数。

template <AttributeType... AttributeList, ApiTypes APIType, typename... PolicyList>
class IShader<Attributes<AttributeList...>, ApiType, Policies<PolicyList...>> 
    : public PolicyList...
{
    ...
};

Then you can even allow the user to specify the arguments in different orders (make sure you forward the constructors if doing it this way via inheritance): 然后,您甚至可以允许用户以不同的顺序指定参数(如果通过继承以这种方式执行,请确保转发构造函数):

template <AttributeType... AttributeList, ApiTypes APIType, typename... PolicyList>
struct IShader<ApiType, Policies<PolicyList...>, Attributes<AttributeList...>
    : public IShader<Attributes<AttributeList...>, ApiType, Policies<PolicyList...>>
{
    using IShader<Attributes<AttributeList...>, ApiType, Policies<PolicyList...>>::IShader;
};

If you're being really fancy, you can even use metaprogramming tricks to allow the arguments in any order without enumerating all orders. 如果你真的很喜欢,你甚至可以使用元编程技巧来允许任何顺序的参数而不枚举所有的命令。 This is left as an exercise to the reader. 这留给读者练习。 :) :)

In the discussion comments you expressed a willingness to consider some kind of indirection, or "a wrapper of some kind for the attribute list". 在讨论评论中,您表示愿意考虑某种间接,或“属性列表的某种包装”。

A lightweight std::tuple -based wrapper, together with specialization, might work here: 一个轻量级的基于std::tuple的包装器,以及特化,可能在这里工作:

template <typename attribute_tuple, APITypes APIType,
          typename policy_tuple> class IShader;

template <AttributeType... Attributes, APITypes APIType,
          class... Policies>
class IShader<std::tuple<Attributes...>, APIType,
              std::tuple<Policies...>> : public Policies... {

// ...

};

The goal here is to use a template instance along the lines of: 这里的目标是使用以下行的模板实例:

IShared<std::tuple<Attribute1, Attribute2>, APITypeFoo,
        std::tuple<Policy1, Policy2>> ishared_instance;

And cross your fingers that this is going to match the specialized template declaration, at which point both parameter packs are available for the template specialization to use, individually. 并指出这将与专门的模板声明相匹配,此时两个参数包都可供单独使用的模板专业化。

Make a nested class, with each layer having one variadic pack.制作一个嵌套类,每一层都有一个可变参数包。 In essence:在本质上:

template<class... ArgsA> class Wrapper {
public:
    template<class... ArgsB> class Type {
        //Here you have access to both template packs
        //...
    }
}
//Use like this:
Wrapper<int, char, long unsigned int>::Type<float, double> a;
//...

Define any function of Type outside both classes, but inside the header, or gcc will get confused.在两个类之外定义任何Type函数,但在头文件中,否则 gcc 会混淆。

For a more complete use case, see my answer here有关更完整的用例,请在此处查看我的答案

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用多参数包可变参数模板继承 class - Inheriting class with multi parameter pack variadic template 多个可变参数函数的单个模板参数包? - Single template parameter pack for multiple variadic functions? 模板模板可变参数包 - template template variadic parameter pack 枚举可变参数模板参数包 - Enumerate variadic template parameter pack C ++模板可变参数类构造函数与参数包一起使用,但功能不起作用 - C++ Template Variadic Class Constructor working with Parameter Pack but functions not 为什么一个可变参数类模板最多具有一个参数包? - Why can a variadic class template have at most one parameter pack? 将参数包args解压缩到可变参数模板中定义的每个类的构造函数中 - Unpacking parameter pack of args into the constructor of each class defined in a variadic template 如果满足条件,则在可变参数模板参数包中调用可变参数模板函子 - Call a variadic template functor in a variadic template parameter pack if it satisfies a condition 具有可变参数模板包的类模板的输出运算符 - Output operator for class template with variadic template pack 获取可变参数模板参数包的依赖类型 - Get dependent type of variadic template parameter pack
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM