EricChen1248
EricChen1248

Reputation: 676

Getting template type from inherited class C++

So I'm trying to populate a custom collection of a class that is inherited from a template class, like so

template<typename T>
class Parent {
public: 
  T value;
  Parent(T val) {value = val;}
}

class ChildA : Parent<int> {
... 
}

class ChildB : Parent<double> {
...
}

// ==== Collections ====
template<typename cT>
class ParentCollection {
public:
  cT list[10];
}

class ACollection : ParentCollection<ChildA> {
...
}

class BCollection : ParentCollection<ChildB> {
...
}

So I want to add a function to ParentCollection that will allow me to generate and add a new cT type the the list array. This should be inherited by the children. If I was to write this in ACollection or BCollection, it would be something like:

void ACollection::Add(int val) {...}

or

void BCollection::Add(double val) {...}

respectively. However, since these both do the exact same thing except generate different Childrens, I would want to write this in the ParentCollection, but I can't figure out how to do something like:

void ParentCollection::Add(T val) {...}

that is, use the T type from the Parent class template in the parms for ParentCollection. Is something like this possible? Or must I write the add functions separately for both child collections.

Upvotes: 2

Views: 2942

Answers (2)

JimPri
JimPri

Reputation: 1407

You can typedef the T type in the parent class and then use it in a derived class:

template <typename T>
class Base
{
  public:
    typedef T BaseT;
};

class Derived : public Base<int>
{
  public:
    static void printBaseType()
    {
      printf("%s\n", typeid(BaseT).name()); // prints "i"
    }
};

Specific instructions for fixing this:

  • In the Parent class, add: typedef T ParentT
  • You can then use the type ChildA::ParentT (int) or ChildB::ParentT (double)
  • In the ParentCollection class, you can expose this again by doing: typedef typename cT::ParentT ParentT
  • In ACollection, you can then access it as ParentT.
  • In ParentCollection, you can write the function declaration as: void Add(ParentT val);
  • The function definition, however, needs to qualify the ParentT type because you are outside of the class scope, so you write: void ParentCollection::Add(ParentCollection::ParentT val) { ... }

Upvotes: 2

Daniel Jour
Daniel Jour

Reputation: 16156

Usually it's a good idea to expose the template parameters, because since C++ has no reflection capabilities it's otherwise a hassle to obtain them outside of the class itself:

// inside parent class
using value_type = T;

You can then reference this typedef to specify your member function signature:

void Add(typename cT::value_type val)

Upvotes: 7

Related Questions