Saif Ullah Saif Ullah - 1 month ago 7
C++ Question

Is it possible for a specialized version to share some functionalities with the original template class?

Is it possible for a specialized version of a class to share some or all functionalities of the original template class?

i.e. consider there is a template class,

template <typename T>
class A
{
A()
{}
A(const A& ref)
{}
void f1()
{
//do something
}
void f2()
{
//do something
}
void f3()
{
//do something
}
}


and it has a specialized version for a specific datatype, which only intend to add some addition functionalities to the generic version in addition the original generic functionalities.

template<>
class A<int>
{
void f4()
{
//do something
}
}


now what I specifically want is that this specialized version to be sharing everything from its generic version including the constructors if possible.

Answer

It is usually possible to implement that by restructuring the class hierarchy:

template <typename T>
class A_base
{
     // All the f1() functions, et. al, implemented here
};

template<typename T> class A : public A_base<T> {

public:

     // An empty shell of a class, with the constructor
     // forwarding its arguments to the superclass.

     template<typename ...Args> A(Args && ..args)
          : A_base(std::forward<Args>(args)...)
     {
     }
};

template<>
class A<int> : public A_base<int>
{
    // Same constructor.

    void f4()
    {
        //do something
    }
};

You end up moving all class methods, class members, into a base class, with your template class consisting of nothing more than deriving from the base class template; and an empty facade otherwise.

Then, your specialization derives from the base class the same way, and adds its own methods.

Another alternative is to implement this kind of derivation "backwards".

// Empty template class.

template<typename T> class A_extra {};

// Your specialization, with the extra method:

template<>
class A_extra<int> {

    void f4()
    {
    }
};

// And the template class inherits from it:

template<typename T> class A : public A_extra<T> {

   // Your template class
};

Depending on the particular details of your template class, one or the other approach should work; or some variation on the same theme.

Comments