开发者

Pointer template specialization

开发者 https://www.devze.com 2023-04-13 04:18 出处:网络
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*).

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];
0

精彩评论

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