以下是我的情况:
基类,没有模板类型:
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
,就好像它是一个虚函数一样吗?
答案 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>
}