Параметры шаблона шаблона с вариационными шаблонами

Для ясности я удалил такие вещи, как конструктор, деструктор и т. Д. Из приведенного ниже списка, где они ничего не добавляют к вопросу. У меня есть базовый класс, который используется для создания общего предка для производного шаблона класса.

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; у каждого свои параметры шаблона. Все идет нормально.

Теперь по вопросу. Я хотел бы иметь возможность создать шаблон контейнера, который не содержал бы ни одной, одной или нескольких производных версий PeripheralSystem внутри него, и я думаю, что я могу использовать переменные шаблоны для этого, но я немного застрял на синтаксис за прошедший день или около того. Во время компиляции я хотел бы иметь возможность создавать экземпляр класса контейнера. Возможно что-то вроде:

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;

Я знаю, что используемый мной вариационный формат неправильный, поскольку я получаю:

ошибка: ожидается ',' или '>' в шаблоне списка параметров-шаблонов <аргументы класса шаблона...>>

То, что я пытаюсь сказать компилятору, - это то, что я хочу предоставить переменное число параметров типа шаблона для шаблона, каждый из которых имеет переменное количество параметров шаблона. Могу ли я сделать это с помощью шаблонов variadic, пожалуйста? Любые предложения по правильному синтаксису, пожалуйста?

1 ответ

Решение

У вас есть многоточие не в том месте. Пытаться:

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

Однако вам не нужны параметры шаблона шаблона; поскольку DerivedSystem1<1> это тип, а не шаблон, вы просто хотите обычные параметры typename:

template<typename... Args>
class ContainerClass {

Для фактического контейнера вы не можете использовать vector<PeripheralSystem> поскольку это однородно и будет разрезать производные типы до PeripheralSystem, Если вы добавите виртуальный деструктор в PeripheralSystem ты можешь использовать vector<unique_ptr<PeripheralSystem>>:

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

Тем не мение, tuple будет работать так же хорошо и приведет к меньшему распределению:

template<typename... Args>
class ContainerClass {
  public:
    ContainerClass() : container{Args{}...} {}
    std::tuple<Args...> container;
};
Другие вопросы по тегам