Search code examples
c++templatesinheritancestlgeneric-programming

Using a template class in STL containers


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.


Solution

  • 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.