指针模板专业化

时间:2011-10-16 19:57:47

标签: c++ templates

我是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函数。 感谢。

4 个答案:

答案 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*>
{...}

下一个困惑是你试图在专业化中使用非专业成员变量。模板专业化与非专业版完全分开。对于此示例,您只在非专用模板中声明了变量OffsetDataLengthValue。如果你想将它们放在那里,你需要将它们添加到专业化中:

template <>
class TProductTableItem<char*>
{
    int             Offset;
    int             DataLength;
    char*           Value;
    ...
}

答案 3 :(得分:0)

您希望memcpy行更像这样:

memcpy(Value, (void*)&buffer[Offset], DataLength);

同样,当你指定价值时:

    Value = (T)&buffer[Offset];