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
Basefunctions from an instantiatedDerivedobject, either inside aDerivedfunction, or explicitly as below withobj1.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:
- Is combining class templates with class inheritance possible in this way?
- Why does the compiler label the Derived class a non-template despite me explicitly using that keyword?
- 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.
Thanks to ravnsgaard and HTNW for the helpful suggestions which got me to a solution. The key was to remove the
template<>keyword from theDerivedclass (because I wanted it to be a class and not a class template) and declaration ofBase<int>at the end of the source file. So the working code looks like this:In myClasses.h
in myClasses.cpp
In main.cpp
In particular, without the
template class Base<int>;declaration at the end of myClasses.cpp, the call toobj1.Foowill fail with an error complaining thatDerivedhas no such function.