Search code examples
c++templatesinheritance

Inherit while using base template identifiers


I have two templates A and B both with the same template types. Always, A inherits from B, but it always chooses the same template for B as A itself uses.

This is fine in and of itself, but this requires me to write the template type twice. Is it possible to somehow typedef the type in A and refer to the generic typedef name when inheriting from the subclass?

Below is some example code that does not compile but should give a clear idea of what I want to do:

// #1
template <typename T>
struct A
{
    typename T type;
    // class details here
};

// #2
template <typename T>
struct B
{
    // class details here
};

// #3
template <>
struct A<int>
    : B<type> // Compiler complains here (type not defined)
    //: B<A::type> // Compiler complains here (type not defined)
    // I could write ": B<int>" instead, but this is repitition I want to avoid
{
    // class specialization details here
};

I'm open for alternative solutions. The reason this is important to me is that I have a large laundry list of code like that of #3 and I want to reduce duplication (to avoid bugs).


Solution

  • Two different specializations of the same template are completely unrelated types*, so you cannot use A<>::type from the base template inside the specialization A<int>. Even if you define type inside the A<int> specialization, it won't be available until the class is defined, which happens after the list of inheritance.

    You could and you should use : B<int> there. It is no more repetition than B<type>, and makes it explicit that A<int> inherits from B<int>, something that is not immediately visible if you go through indirections.

    Another thing that kind of bugs me from your design is that A<> (the generic one) does not have any relationship with B<>, but A<int> inherits from B<int>. While the language allows for completely unrelated behavior in specializations, that might be surprising to other programmers, when they can pass objects of A<T> to functions taking B<T> for some T, but not for others...

    What is the actual problem that you want to get solved?


    * The implication of this is that an specialization does not provide special behavior (i.e. only the bits that differ from the base) but all the behavior of that type. If you only mean to override part of the behavior you should consider other alternatives, like refactoring A<T> (generic) into a base so that A<int> (or other specializations) can borrow the implementation. Or if the changes in behavior are small you might be able to just specialize some of the member functions...