模板模板参数与可变模板 [英] Template template parameters with variadic templates

查看:146
本文介绍了模板模板参数与可变模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了清楚起见,我删除了一些东西,比如构造函数&析构函数等从下面他们不添加任何东西的问题。我有一个基类,用于为派生模板类创建一个共同的祖先。

For the sake of clarity, I've removed things like the constructor & destructor etc from the below where they don't add anything to the question. I have a base class that is used to create a common ancestor for a derived template class.

class PeripheralSystemBase {
public:
    virtual void someFunctionThatsCommonToAllPeripherals() {}
};

template <class T, uint32_t numPeripherals = 1>
class PeripheralSystem : public PeripheralSystemBase {
public:
    PeripheralSystem() : vec(T) {}
    std::vector<T> vec;  // different types of T is the reason why I need to template this class
};

// A & B declaration & definition are irrelevant here
class A{};
class B{};

// There are multiple different derived variants of PeripheralSystem
// At the moment, each has different template parameters

template <uint32_t customisableParam1>
class DerivedSystem1 : public PeripheralSystem<A, 1> {
public:
    DerivedSystem1() : PeripheralSystem<A, 1>() {}
};

template <uint32_t customisableParam1, uint8_t customisableParam2>
class DerivedSystem2 : public PeripheralSystem<B, 1> {
public:
    DerivedSystem2() : PeripheralSystem<B, 1>() {/*maybe use customisableParam2 here */}
};

现在我有2个模板类,每个派生自同一个祖先类,一个包含一个向量类型A,另一种类型B;每个都有不同的模板参数。到目前为止,这么好。

So now I have 2 templates classes, each derived from the same ancestor class, one containing a vector containing type A, the other of type B; each has different template parameters. So far, so good.

现在问题。我想能够创建一个容器模板,不包含一个或多个派生版本的PeripheralSystem里面,我想我可以使用可变参数模板来做到这一点,但我有一个卡住了在过去一天左右的语法。在编译时,我想要能够创建一个容器类的实例。可能类似:

Now for the question. I would like to be able to create a container template to contain none, one or more of the derived versions of PeripheralSystem inside it and I think I may be able to use variadic templates to do this, but I've got a bit stuck on the syntax over the past day or so. At compile time, I'd like to be able to create an instance of the container class. Perhaps something like:

template< template<typename ...> class args...>
class ContainerClass {
  public:
    ContainerClass() : container({args}) {}
    std::vector<PeripheralSystem> container;
};

// possible usage
ContainerClass<DerivedSystem1<1>> cc1;
ContainerClass<DerivedSystem2<2, 3>> cc2;
ContainerClass<DerivedSystem1<1>, DerivedSystem2<2, 3>> cc3;

我知道我使用的可变格式是不正确的,因为我得到:

I know the variadic format I'm using isn't right, as I get:


错误:模板参数列表模板中的预期','或'>'
模板类args ...>>

error: expected ',' or '>' in template-parameter-list template< template class args ...> >

我想告诉编译器,向模板可变数量的模板类型参数,每个模板类型参数具有可变数量的模板参数。我能做到这一点与variadic模板吗?对正确的语法有什么建议吗?

What I'm trying to tell the compiler is that I want to supply a variable number of template-type parameters to the template, each of which has a variable number of template parameters. Am I able to do this with variadic templates please? Any suggestions on the correct syntax please?

推荐答案

你的省略号在错误的地方。尝试:

You've got your ellipsis in the wrong place. Try:

template<template<typename...> class... Args>
                                    ^^^ here

但是,你实际上不需要模板模板参数;由于 DerivedSystem1< 1> 是一个类型,而不是一个模板,你只需要普通的typename参数:

However, you don't actually want template template parameters; since DerivedSystem1<1> is a type, not a template, you just want ordinary typename parameters:

template<typename... Args>
class ContainerClass {

对于实际容器,不能使用 vector< PeripheralSystem> ,因为它是同构的,并且将派生类型分成 PeripheralSystem 。如果你向 PeripheralSystem 添加一个虚拟析构函数,你可以使用 vector< unique_ptr< PeripheralSystem>>

For the actual container, you can't use vector<PeripheralSystem> as that is homogeneous and will slice the derived types down to PeripheralSystem. If you add a virtual destructor to PeripheralSystem you can use vector<unique_ptr<PeripheralSystem>>:

template<typename... Args>
class ContainerClass {
  public:
    ContainerClass() : container{std::make_unique<Args>()...} {}
    std::vector<std::unique_ptr<PeripheralSystem>> container;
};

但是, tuple 并导致较少的分配:

However, tuple would work just as well and result in fewer allocations:

template<typename... Args>
class ContainerClass {
  public:
    ContainerClass() : container{Args{}...} {}
    std::tuple<Args...> container;
};

这篇关于模板模板参数与可变模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆