Search code examples
c++ooptemplatesinheritancevirtual

Virtual Template Workarounds


I have a template container class that I derive from called MyContainer. MyContainer defines methods like Get(), Set(), etc. to access individual elements. I'd like to make a bitfield class implemented as a MyContainer<char>, where each char element holds CHAR_BIT number of bits. However, to allow the user to operate on individual bits rather than entire bytes, I would have to make Get() and Set() virtual, which is illegal. What are some alternatives?

I was thinking of defining GetBit() and SetBit() in the derived class, but this would violate the Liskov substitution principle. (Think of a SortMyContainer() function.)

EDIT: Here is a simplified example:

template <typename Datatype>
struct MyContainer
{
    virtual Datatype Get();
};

template <typename Datatype> // Error: Templates may not be virtual.
virtual Datatype MyContainer<Datatype>::Get() // EDIT: The problem was on this line.  The "virtual" keyword should only appear with the function declaration.
{
    // ...
}

Solution

  • It is not illegal, only template virtual member functions are.

    // valid
    template<typename T> class MyContainer {
        virtual void set(const T &) = 0;
    }
    
    // not valid
    class MyContainer {
        template <typename T> virtual void set (const T &) = 0;
    }
    

    If I got you wrong, please consider placing a code-sample.

    edit after your adding of example code:

    template <typename Datatype>
    virtual // <-- nope, not here
    Datatype MyContainer<Datatype>::Get()
    {
        // ...
    }
    

    virtual is only part of the declaration inside the class body. This should be valid:

    template <typename Datatype>
    Datatype MyContainer<Datatype>::Get()
    {
        // ...
    }
    

    However, note that the definition must be visible at the point of template instantiation. So either put it in the header-file, too (or in an extra-header that you then include into your real header), or leave it in the class-body.

    (please nobody mention exported templates now, you and I know them a lot, but they are not quite a beginner topic, and deprecated with the next standard)