If I have a template class, that I want to instantiate with different data types:
template <typename T>
class A {
T value;
// ...
};
And I also want to use the objects of this class in a Standard Template Library container (say vector
).
In my understanding creating a vector of A
objects would not be accepted by the compiler, because A<int>
and A<char>
are actually different types and I can't put them in the same vector.
The workaround I found was creating a base class, a derived template class, and a vector of base class pointers.
class ABase {
// ...
};
template <typename T>
class ADerived : public ABase{
T value;
// ...
};
std::vector<BaseA*> mySuperVector;
I am starting to experiment with templates to gain a better understanding and I am wondering whether there are better solutions for this. My workaround above gives me also headache, because I am afraid that typecasting will be inevitable at some point.
Templates are a compile-time code generation construct. If you need an heterogeneous container of objects at compile-time, then you can use std::tuple
:
std::tuple my_tuple{A<int>{}, A<char>{}, A<double>{}};
If you need an heterogeneous container of objects at run-time, you do need some sort of polymorphism. Using a base class with virtual
methods is a valid option. If you know all the possible choice of types your object can be in advance, you can also use std::variant
:
using my_a = std::variant<A<int>, A<char>, A<double>>;
std::vector<my_a> vec;
In this case, my_a
can either be A<int>
, A<char>
, or A<double>
at any given time. The active alternative can change at run-time.