【问题标题】:Polymorphic Explicit Template Instantiation多态显式模板实例化
【发布时间】:2010-11-17 16:11:22
【问题描述】:

有这个基本的层次结构:

// header

class Base
{
    virtual void method() { }
    virtual ~method() { }
};

class Subclass : Base
{
    virtual void method() { }
    virtual ~method() { }
};

我希望用两个显式变体子类化 Base(如果可能,不必提供 Subclass 的两个实现),因此建议使用显式模板实例化:

// header

class Base
{
    virtual void method() { }
    virtual ~method() { }
};

class Base1 : public Base { };
class Base2 : public Base { };

template <typename T>    
class Subclass : public T
{
    virtual void method();
    virtual ~method() { }
};

// cpp

template <typename T>
void Subclass<T>::method()
{
}

template class Subclass<Base1>;
template class Subclass<Base2>;

我收到此错误:

“方法”没有参数 取决于模板参数, 所以必须声明“方法” 可用

这是正确的方法吗?我显然必须模板 Base 才能编译,但是用什么?

【问题讨论】:

  • 不要忘记虚拟析构函数。与金钱不同,与性不同,你需要索取,否则你得不到。

标签: c++ templates inheritance instantiation


【解决方案1】:

你应该把你的模板类和函数的定义放在头文件中(它必须对使用它们的人可见)。

只能声明完整的特化(并在您的代码不可见的地方定义)。

此外,如果你想在类之外定义一个类模板的函数(就像你所做的那样),你必须将它声明为一个模板:

template< typename T > 
void Class<T>::method( )
{
}

无论如何,如果我没记错的话,您引用的错误是在您使用由您继承的类型名提供的函数 method 时给出的(我认为您还没有发布生成错误...):只有在模板实际实例化时才能找到,因此需要明确表示它取决于模板参数。

这样拨打method

T::method();

【讨论】:

  • 理想情况下,我不希望将定义放入头文件,因为计算量很大,如果可以避免的话,编译时间会大大增加?
  • 那么在不知道基类是什么的情况下就没有办法使用多态调用method()?
  • 此时您希望在标头之外拥有模板,这真是太不幸了。尝试说服您的编译器供应商为模板实现“导出”......祝你好运。如果不知道定义基的派生中的基是什么,就无法在基中调用method()。如果您从子类中删除 method() 它将起作用。否则,您必须使用答案中提到的语法。
  • @Dan 将模板保存在 .cpp 文件中没有任何问题。修复两个错误(“template”一个和“T::method()”一个)就可以了。对于 T::method 错误,您也可以want to look here。我希望有些人不要再鼓吹“模板只能在标题中工作”的谬论。
【解决方案2】:

问题及解决方案的简要总结:

要使用模板化基类中的方法,需要使用模板参数:

T::method();

或简单地使用“this”来允许在不明确知道模板参数的情况下找到它:

this->method();

感谢那些指出我找到此解决方案的人,我不知道这一点。还想指出将模板放在 cpp 文件中没有问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    • 1970-01-01
    • 2021-05-02
    • 2021-07-18
    • 1970-01-01
    • 1970-01-01
    • 2013-01-18
    相关资源
    最近更新 更多