1
votes

Here is my situation:

Base class, no templated type:

struct Thing
{

} ;

Templated class, extends that very base class

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

Derived class, CONCRETE type (no template)

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

But template typename<S> bool VertexWriter<T>::intersects cannot be marked virtual, because it is a template class.

There are many classes that derive from the VertexWriter<VertexPNCT> specialization, so template specializing VertexWriter<VertexPNCT> would not work.

So the normal thing to do is to provide a template specialization.

But Rocket specifies it is a VertexWriter<VertexPNCT>, so it is no longer a template class. Can it specialize OR override intersects as if it were a virtual function?

3

3 Answers

1
votes

No, as you've stated you cannot use virtual functions, which would provide runtime polymorphism.

That said, depending on what leeway you have on changing the layout of your classes, you might be able to do something using 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>
} ;

The base implementation of intersects simply forwards to the CRTP function. If the derived class overrides it, it'll use the override, but otherwise it'll fall back the default. Note, this does complicate your class hierarchy, but might accomplish what you're looking for.

0
votes

No, you cannot.

Templated member functions cannot be virtual.

It doesn't matter whether VertexWriter is templated, specialized, or a normal class.

0
votes

You could template VertexWriter on S and make intersects a virtual function of that class template

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

Now you can override intersects in a derived class

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