我是C ++模板的新手,所以这是我的问题。
我有一个通用类ProductItem,可以完成我想要的所有东西,但我需要专门化一个部分才能使用指针(对于char *)。
我的代码:
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;
}
};
尝试编译此代码时,我出现以下错误消息:
cannot convert from 'const BYTE' to 'char*'
我做错了什么?
即使对于char*
类型,它看起来也是如此,它会尝试使用TProductTableItem::LoadFromBuffer
函数而不是TProductTableItemString::LoadFromBuffer
函数。
感谢。
答案 0 :(得分:4)
TProductTableItemString
通过继承,导致TProductTableItem<char*>
的实例化。在TProductTableItem::LoadFromBuffer
的实现中,这一行:
Value = buffer[Offset];
无法编译,因为缓冲区[Offset]是一个字节,而Value是char *。
顺便说一下,TProductTableItemString
不是专业化,它只是继承然后隐藏LoadFromBuffer
。如果你真的想要专攻,你应该写:
template<>
class TProductTableItem<char*>
{
...
};
答案 1 :(得分:2)
您正在混合两个不同的概念:继承和模板特化。
您的课程不是模板专业化,但从模板实例化中派生。但是,该模板无法实例化,因为当T = char *
语句Value = buffer[offset];
出现类型不匹配错误时。
如果要编写模板专门化,则语法为
template<>
class ProductTableItem<char *> {
...
};
请注意,从继承的角度来看,两个模板实例化通常是不相关的类型...
可能是您尝试做的事情的解决方案就像
// 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) {
...
}
};
我说可能,因为我确实不清楚你想要完成什么。
答案 2 :(得分:1)
你混淆了继承和专业化的概念。首先,为了专门化模板,你不是从它派生的 - 你使用这种语法:
template <>
class TProductTableItem<char*>
{...}
下一个困惑是你试图在专业化中使用非专业成员变量。模板专业化与非专业版完全分开。对于此示例,您只在非专用模板中声明了变量Offset
,DataLength
和Value
。如果你想将它们放在那里,你需要将它们添加到专业化中:
template <>
class TProductTableItem<char*>
{
int Offset;
int DataLength;
char* Value;
...
}
答案 3 :(得分:0)
您希望memcpy行更像这样:
memcpy(Value, (void*)&buffer[Offset], DataLength);
同样,当你指定价值时:
Value = (T)&buffer[Offset];