首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有可变模板的模板参数

带有可变模板的模板参数
EN

Stack Overflow用户
提问于 2014-07-17 20:27:03
回答 1查看 922关注 0票数 2

为了清晰起见,我从下面删除了构造函数和析构函数等内容,它们没有为问题添加任何内容。我有一个基类,用于为派生模板类创建公共祖先。

代码语言:javascript
复制
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 */}
};

现在我有两个模板类,每个模板类都来自同一个祖先类,一个包含包含A类型的向量,另一个包含B类型的向量;每个模板参数都不同。到现在为止还好。

现在轮到问题了。我希望能够创建一个容器模板,以便在其中包含任何、一个或多个派生版本的PeripheralSystem,我认为我可能能够使用各种模板来实现这一点,但在过去的一天左右,我在语法上遇到了一些问题。在编译时,我希望能够创建容器类的实例。也许是这样的:

代码语言:javascript
复制
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;

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

错误:模板参数列表中的template<模板类...> >中的“、”或“class‘>”

我试图告诉编译器的是,我想向模板提供一个可变数量的模板类型参数,每个模板都有一个可变数量的模板参数。我能用不同的模板做这个吗?请对正确的语法提出建议吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-07-17 20:32:57

你把省略号放错地方了。尝试:

代码语言:javascript
复制
template<template<typename...> class... Args>
                                    ^^^ here

但是,实际上并不需要模板模板参数;因为DerivedSystem1<1>是类型,而不是模板,所以您只需要普通的类型名称参数:

代码语言:javascript
复制
template<typename... Args>
class ContainerClass {

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

代码语言:javascript
复制
template<typename... Args>
class ContainerClass {
  public:
    ContainerClass() : container{std::make_unique<Args>()...} {}
    std::vector<std::unique_ptr<PeripheralSystem>> container;
};

然而,tuple的工作效果也很好,并且会导致分配的减少:

代码语言:javascript
复制
template<typename... Args>
class ContainerClass {
  public:
    ContainerClass() : container{Args{}...} {}
    std::tuple<Args...> container;
};
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24812913

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档