你能模板化一个非模板化的子类吗?

时间:2013-01-24 19:28:38

标签: c++ templates template-specialization virtual-functions

以下是我的情况:

基类,没有模板类型:

struct Thing
{

} ;

模板化类,扩展了那个基类

template <typename T> struct VertexWriter : public Thing
{ 
    template <typename S>
    bool intersects( S* otherThing )
    {
        // has a body, returns T or F
    }
} ;

派生类,CONCRETE类型(无模板)

struct Rocket : VertexWriter<VertexPNCT>
{
    template <typename S>
    bool intersects( S* otherThing ) ; // WANTS TO OVERRIDE
    // implementation in VertexWriter<T>
} ;

template typename<S> bool VertexWriter<T>::intersects无法标记为虚拟,因为它是模板类。

有很多类派生自VertexWriter<VertexPNCT>专精,因此专门化VertexWriter<VertexPNCT>的模板不起作用。

所以正常的做法是提供模板专业化。

Rocket指定它是VertexWriter<VertexPNCT>,因此它不再是模板类。它可以专门化或覆盖intersects,就好像它是一个虚函数一样吗?

3 个答案:

答案 0 :(得分:1)

不,正如您所说,您不能使用虚拟功能,这将提供运行时多态性。

那就是说,根据你改变课程布局的余地,你可以用CRTP做点什么。

template <typename T, typename Derived> struct VertexWriter : public Thing
{ 
    template <typename S>
    bool intersects( S* otherThing )
    {
        return static_cast<Derived*>(this)->insersects_impl(otherThing);
    }

    template<typename S>
    bool insersects_impl( S* otherThing)
    {
         // Whatever
    }
} ;

struct Rocket : VertexWriter<VertexPNCT, Rocket>
{
   template <typename S>
   bool intersects_impl( S* otherThing ) { ... } // WANTS TO OVERRIDE
                       // implementation in VertexWriter<T>
} ;

intersects的基本实现只是转发到CRTP函数。如果派生类重写它,它将使用覆盖,否则它将回退默认值。请注意,这确实会使您的类层次结构变得复杂,但可能会实现您正在寻找的内容。

答案 1 :(得分:0)

不,你不能。

模板化成员函数不能是虚拟的。

VertexWriter是模板化的,专用的还是普通的类都无关紧要。

答案 2 :(得分:0)

您可以在VertexWriter上模板S,并使intersects成为该类模板的虚拟功能

template <typename T, typename S> struct VertexWriter : public Thing
{ 
    virtual bool intersects( S* otherThing )
    {
        // has a body, returns T or F
    }
} ;

现在,您可以在派生类

中覆盖intersects
template<typename S>
struct Rocket : VertexWriter<VertexPNCT, S>
{
    virtual bool intersects( S* otherThing ) ; // WANTS TO OVERRIDE
    // implementation in VertexWriter<T>
}