0

我有一个实现许多功能的类模板。当声明特定类型时,我还希望能够添加此类的专用版本,该版本只有少数功能覆盖基类的功能。我知道我可以通过一个类模板和它的显式特化来实现这一点。但是我也想:

  • 具有唯一命名的显式特化,类似于如何唯一命名基类和派生类。
  • Base从实例化Derived对象调用函数,无论是在Derived函数内部,还是如下所示显式调用obj1.Foo

这是我试图使工作的(简化)示例代码:

在 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;
}

在 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 }

在 main.cpp

int main()
{
  Base<int> obj1 = new Derived();
  obj1.Foo(input);                  // Runs Base::Foo
  obj1.Bar(input);                  // Runs Derived::Bar
}

但是,此代码因explicit specialization of non-template Derived错误等而失败。我已经阅读了很多 StackOverflow 线程来让我走到这一步,但我还没有找到任何可以帮助我进行编译的东西。所以我的问题是:

  1. 是否可以通过这种方式将类模板与类继承结合起来?
  2. 尽管我明确使用该关键字,为什么编译器仍将派生类标记为非模板?
  3. 使此代码工作的正确语法是什么?(假设我正在尝试做的事情是可能的)

编辑:按照 HTNW 的建议,我可以通过删除前缀Derived变成普通类。template<>这将允许一切编译到obj1.Foo(input). 实例化的 Derived 类似乎无法找到或访问基 Foo 函数。

4

1 回答 1

0

感谢 ravnsgaard 和 HTNW 提供的有用建议,让我找到了解决方案。关键是从类中删除template<>关键字Derived(因为我希望它是一个类而不是类模板)和Base<int>源文件末尾的声明。所以工作代码如下所示:

在 myClasses.h

template<typename T>
class Base
{
  public: 
    void Foo (T& input);
    virtual void Bar (T& input);
}

class Derived : public Base<int>
{
  public: 
    void Bar (int& input) override;
}

在 myClasses.cpp

template<typename T>
Base::Foo(T& input) { // Do something generic }

template<typename T>
Base::Bar(T& input) { // Do something generic }

Derived::Bar(int& input) { // Do something int-dependent }

template class Base<int>; // VERY IMPORTANT.

在 main.cpp

int main()
{
  Base<int> &&obj1 = Derived();
  obj1.Foo(input);                  // Runs Base::Foo
  obj1.Bar(input);                  // Runs Derived::Bar
}

特别是,如果没有template class Base<int>;myClasses.cpp 末尾的声明,调用obj1.Foo将失败,并抱怨Derived没有此类功能的错误。

于 2020-07-15T02:11:35.353 回答