Explicit Specialization of a Derived Class Template

548 Views Asked by At

I have a class template that implements a number of functions. I want to be able to also add specialized version of this class which has only a few functions that override those of the base, when a specific type is declared. I know I could achieve this with a class template and explicit specializations of it. However I also want to:

  • Have the explicit specializations uniquely named, similar to how a base and derived class are uniquely named.
  • Call the Base functions from an instantiated Derived object, either inside a Derived function, or explicitly as below with obj1.Foo

This is the (simplified) example code I am trying to make work:

In myClasses.h

template<typename T>
class Base
{
  public: 
    void Foo (T& input);
    virtual void Bar (T& input);
}

template<>
class Derived : public Base<int>
{
  public: 
    void Bar (int& input) override;
}

In myClasses.cpp

template<typename T>
Base::Foo(T& input) { // Do something generic }

template<typename T>
Base::Bar(T& input) { // Do something generic }

template<>
Derived::Bar(int& input) { // Do something int-dependent }

In main.cpp

int main()
{
  Base<int> obj1 = new Derived();
  obj1.Foo(input);                  // Runs Base::Foo
  obj1.Bar(input);                  // Runs Derived::Bar
}

However this code fails with the explicit specialization of non-template Derived error, among others. I've read a lot of StackOverflow threads to get me this far, but I haven't found any that have helped me make this compile. So my questions are:

  1. Is combining class templates with class inheritance possible in this way?
  2. Why does the compiler label the Derived class a non-template despite me explicitly using that keyword?
  3. What is the correct syntax that will make this code work? (assuming what I am trying to do is possible)

EDIT: Following the suggesting of HTNW, I can turn Derived into a regular class by removing the template<> prefix. This will allow everything to compile up to obj1.Foo(input). It seems that the instantiated Derived class can't find or access the base Foo function.

1

There are 1 best solutions below

0
On

Thanks to ravnsgaard and HTNW for the helpful suggestions which got me to a solution. The key was to remove the template<> keyword from the Derived class (because I wanted it to be a class and not a class template) and declaration of Base<int> at the end of the source file. So the working code looks like this:

In myClasses.h

template<typename T>
class Base
{
  public: 
    void Foo (T& input);
    virtual void Bar (T& input);
}

class Derived : public Base<int>
{
  public: 
    void Bar (int& input) override;
}

in myClasses.cpp

template<typename T>
Base::Foo(T& input) { // Do something generic }

template<typename T>
Base::Bar(T& input) { // Do something generic }

Derived::Bar(int& input) { // Do something int-dependent }

template class Base<int>; // VERY IMPORTANT.

In main.cpp

int main()
{
  Base<int> &&obj1 = Derived();
  obj1.Foo(input);                  // Runs Base::Foo
  obj1.Bar(input);                  // Runs Derived::Bar
}

In particular, without the template class Base<int>; declaration at the end of myClasses.cpp, the call to obj1.Foo will fail with an error complaining that Derived has no such function.