没有为显式模板实例化请求提供合适的定义

时间:2018-05-26 13:13:07

标签: c++ templates

我有一个Calculator<T>类和一个LoggingCalculator<T>类,它继承自Calculator<T>Calculator<T>有一个虚拟方法,如addmultiply等。在子类LoggingCalculator<T>中,我试图覆盖这些方法。我已经覆盖了add方法,很好。但是我无法覆盖multiply,因为编译器说:

  

Calculator :: Calculator [int] :: Calculator(void)&#39;:没有为显式模板实例化请求提供合适的定义

尽管如此,我明确地实例化了我的模板。我真的不明白,为什么在覆盖multiply方法时出现此错误,而add编译正常

真正奇怪的是,如果我不返回从基类方法返回的泛型值,它编译。但是如果想从基类方法返回结果,则不进行编译。请参阅下面的LoggingCalculator.cpp代码。

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
}

1 个答案:

答案 0 :(得分:3)

您必须将显式实例化移动到各自的源文件。这是因为您实例化的定义需要在实例化时可访问。

您正在做的事情现在实例化Calculator<int>类的定义,并使用它Calculator<int>::add声明,但它确实如此不实例化Calculator<int>::add定义,因为该定义不可用。

由于显式模板即时化是一个定义,它通常不会出现在头文件中 - 这可能会导致多重定义问题。