I have a variadic class template that is used to create a top-level class for a variable number of classes. Each class that is to go in the top-level class is derived from a base class, as there is common functionality for them. I don't know the best way to store the derived classes in the parent class, but still be able to access the full functionality of the derived class.
If I store the variadic args in a vector, they'll all be stored as a base class and I can't access the derived functionality. If I store them in a tuple, I can't work out how to access the functions by derived type. If I try to access them as discussed here on SO then make_unique isn't available (C++14?).
So, I want to do the following:
class BaseElement {
public:
virtual int polymorphicFunction() {return 0;};
};
class DerivedElement1 : public BaseElement {
public:
virtual int polymorphicFunction() {return 1;};
}
class DerivedElement2 : public BaseElement {
public:
virtual int polymorphicFunction() {return 2;};
}
template<typename... systems> // systems will always be of derived class of BaseElement
class System {
System() : subsystems(systems{}...) {} ; // all variadic elements stored in tuple
// tuple used below, the system elements don't need to be stored in a container, I just want to access them
// I'd be happy to use a vector or access them directly as a member variable
// provided that I can access the derived class. I can't use RTTI.
const std::tuple<systems...> subSystems;
// pointer or reference, I don't mind, but pd1/2 will always exist,
// (but perhaps be NULL), even if there is no derived element passed to the template parameter
DerivedElement1 *pd1;
DerivedElement2 *pd2;
};
//Desired usage
System<DerivedElement1> sys; // sys->pd1 == &derivedElement1WithinTuple, sys->pd2 == NULL
System<DerivedElement2> sys; // sys->pd2 == &derivedElement2WithinTuple, sys->pd2 == NULL
System<DerivedElement1, DerivedElement2> sys; // sys->pd1 == &derivedElement1WithinTuple, sys->pd1 == &derivedElement1WithinTuple
Does anyone have any suggestions as to how I might achieve this please?
With:
You may have: