Reputation: 610
I have a Calculator<T>
class and a LoggingCalculator<T>
class, which inherites from Calculator<T>
. Calculator<T>
has a virtual methods like add
, multiply
etc. In a child class LoggingCalculator<T>
I am trying to override these methods. I have already overrided the add
method, fine. But I cannot override multiply
, because compiler says:
Calculator::Calculator[int]::Calculator(void)': no suitable definition provided for explicit template instantiation request
even though, I explicitly instantiated my templates. I really do not understand, why this error occures with overriding multiply
method, while add
compiles fine.
The really weird thing is that it does compile, if I do not return generic value returned from base class method. But If want to return result from the base class method, it does not compile. See LoggingCalculator.cpp
code below.
Calculator.h:
template <class T>
class Calculator
{
public:
Calculator();
~Calculator();
virtual T add(T a, T b);
virtual T multiply(T a, T b);
}
template class Calculator<int>;
template class Calculator<long>;
template class Calculator<float>;
template class Calculator<double>;
Calculator.cpp:
template<class T>
Calculator<T>::Calculator() {}
template<class T>
Calculator<T>::~Calculator() {}
template<class T>
T Calculator<T>::add(T a, T b)
{
return a + b;
}
template<class T>
T Calculator<T>::multiply(T a, T b)
{
return a * b;
}
LoggingCalculator.h:
template <class T>
class LoggingCalculator : public Calculator<T>
{
public:
LoggingCalculator();
~LoggingCalculator();
T add(T a, T b) override;
T multiply(T a, T b) override;
};
template class LoggingCalculator<int>;
template class LoggingCalculator<long>;
template class LoggingCalculator<float>;
template class LoggingCalculator<double>;
LoggingCalculator.cpp:
template<class T>
LoggingCalculator<T>::LoggingCalculator() { }
template<class T>
LoggingCalculator<T>::~LoggingCalculator() {}
template<class T>
T LoggingCalculator<T>::add(T a, T b)
{
T result = Calculator<T>::add(a, b);
return result;
}
template<class T>
T LoggingCalculator<T>::multiply(T a, T b)
{
T result = Calculator<T>::multiply(a, b);
//return a * b; // COMPILES FINE!
return result // CAUSES ERROR
}
Upvotes: 2
Views: 1662
Reputation: 171127
You'll have to move the explicit instantiations to their respective source files. That's because definitions of what you're instantiating need to be accessible at the point of instantiation.
What you're doing now instantiates the definition of the class Calculator<int>
and with it, the declaration of Calculator<int>::add
, but it does not instantiate the definition of Calculator<int>::add
, because the definition is not available.
And since explicit template instantation is a definition, it should normally not appear in a header file anyway — that would likely lead to multiple-definition issues down the line.
Upvotes: 3