开发者

Virtual Template Workarounds

开发者 https://www.devze.com 2023-03-12 04:32 出处:网络
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

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.
{
    // ...
}


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)


You appear to be confused about what constitutes a template. Class templates may have virtual functions, and indeed, those template parameters may appear in those function's signatures.

template<typename T> class an_interface {
    virtual T Get() = 0;
};
class a_class : public an_interface<int> {
};

This is perfectly valid. What's not perfectly valid is

class an_interface {
    template<typename T> virtual T Get() = 0;
}

Unless the specific member function in question has it's own, separate template parameters, the member function is not a template and may be virtual, irrespective of if it was generated from a class template.

0

精彩评论

暂无评论...
验证码 换一张
取 消