模板模板参数与可变模板 [英] Template template parameters with variadic templates
问题描述
为了清楚起见,我删除了一些东西,比如构造函数&析构函数等从下面他们不添加任何东西的问题。我有一个基类,用于为派生模板类创建一个共同的祖先。
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屋!