【问题标题】:no suitable definition provided for explicit template instantiation request没有为显式模板实例化请求提供合适的定义
【发布时间】:2018-11-05 16:14:07
【问题描述】:

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

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

尽管如此,我还是明确地实例化了我的模板。我真的不明白,为什么在覆盖 multiply 方法时会发生此错误,而 add 编译良好​​strong>。

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

计算器.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>;

计算器.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
}

【问题讨论】:

  • 天哪,我在return result 之后添加了分号,现在它可以编译了。似乎这只是一个语法错误。

标签: c++ templates


【解决方案1】:

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

你现在正在做的是实例化Calculator&lt;int&gt; 类的定义 以及Calculator&lt;int&gt;::add声明,但它没有实例化Calculator<int>::add 的em>定义,因为定义不可用。

由于显式模板实例化是一个定义,它通常不应该出现在头文件中——这可能会导致多定义问题。

【讨论】:

  • 仍然,为什么添加工作正常?我很好奇,否则肯定喜欢你的回答。
  • 也许我会喜欢你的回答,但你如何解释这个?我在return result 之后添加了分号,现在它可以编译了。好像只是语法错误……
  • @Darko 它为您工作纯属偶然。在标题中,Calculator 实例化出现在两个翻译单元(= 预处理的源文件)中,但只有其中一个具有实际实例化它们的定义。尽管如此,在语义上,实例属于标题。
  • @Darko 不包含 cpp 文件。
  • @Darko 找到good book in our list :-) 但问题是,由于实例化在标题中,它会出现在预处理的LogicCalculator.cpp 中。并且那个没有看到来自Calculator.cpp的定义(记住目标文件是相互独立的!)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-25
  • 2021-05-02
  • 2022-01-01
相关资源
最近更新 更多