Параметры шаблона шаблона с вариационными шаблонами
Для ясности я удалил такие вещи, как конструктор, деструктор и т. Д. Из приведенного ниже списка, где они ничего не добавляют к вопросу. У меня есть базовый класс, который используется для создания общего предка для производного шаблона класса.
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;
};