I'm new to templates in C++, so here is my problem.
I've a generic class ProductItem that will do all the stuff I want, but I need to specialize a part in order to use pointers (for char*).
My code :
typedef unsigned char BYTE;
template<typename T>
class TProductTableItem
{
protected:
int Offset;
int DataLength;
T Value;
public:
virtual bool LoadFromBuffer(const BYTE* buffer, int count)
{
if(Offset + DataLength > count)
return false;
Value = buffer[Offset];
return true;
}
};
// Specialization (doesn't compile)
class TProductTableItemString : public TProductTableItem<char*>
{
bool LoadFromBuffer(const BYTE* buffer, int count)
{
if(Offset + DataLength > count)
开发者_运维技巧 return false;
memset(Value, 0, DataLength);
memcpy(Value, (void*)&buffer[Offset], DataLength);
return true;
}
};
When trying to compile this code, I've the following error message:
cannot convert from 'const BYTE' to 'char*'
What I'm doing wrong?
It look like that even for char*
type, it tries to use the TProductTableItem::LoadFromBuffer
function and not the TProductTableItemString::LoadFromBuffer
one.
Thanks.
TProductTableItemString
, by inheriting from it, causes an instantiation of TProductTableItem<char*>
. In the implementation of TProductTableItem::LoadFromBuffer
, this line:
Value = buffer[Offset];
cannot be compiled because buffer[Offset] is a byte, and Value is a char*.
By the way, TProductTableItemString
is not a specialization, it is simply inheriting and then hiding LoadFromBuffer
. If you really want to specialize, you should write:
template<>
class TProductTableItem<char*>
{
...
};
You are mixing two distinct concepts: inheritance and template specialization.
Your class is not a template specialization but it derives from a template instantiation. However that template cannot be instantiated because when T = char *
the statement Value = buffer[offset];
has a type mismatch error.
If you want to write a template specialization then the syntax is
template<>
class ProductTableItem<char *> {
...
};
Note that two templates instantiations are in general unrelated types from an inheritance point of view...
May be a solution for what you are trying to do is something like
// Non-template base class
class ProducTableItemBase {
protected:
...
public:
virtual bool LoadFromBuffer(const BYTE* buffer, int count) = 0;
};
// Template class for all other types
template<typename T>
class ProductTableItem : public ProductTableItemBase {
T Value;
bool LoadFromBuffer(const BYTE* buffer, int count) {
...
}
};
// Template specialization for char*
template<>
class ProductTableItem<char *> : public ProductTableItemBase {
char * Value;
bool LoadFromBuffer(const BYTE* buffer, int count) {
...
}
};
I said may be because indeed it's not clear to me what you are trying to accomplish.
You are confusing the concepts of inheritance and specialisation. Firstly, in order to specialise a template, you don't derive from it - you use this syntax:
template <>
class TProductTableItem<char*>
{...}
The next confusion is that you are trying to use the non-specialised member variables in the specialisation. Template specialisations are are completely seperate to the non-specialised version. For this example, you have only declared the variables Offset
, DataLength
and Value
inside the non-specialised template. You need to add these to the specialisation if you want to have them there:
template <>
class TProductTableItem<char*>
{
int Offset;
int DataLength;
char* Value;
...
}
You want your memcpy line to be more like this:
memcpy(Value, (void*)&buffer[Offset], DataLength);
And likewise when you assign Value:
Value = (T)&buffer[Offset];
精彩评论