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.
{
// ...
}
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 export
ed 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.
精彩评论