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 instantiatedDerived
object, either inside aDerived
function, 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 theDerived
class (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.Foo
will fail with an error complaining thatDerived
has no such function.