Указатель шаблона специализации - PullRequest
0 голосов
/ 16 октября 2011

Я новичок в шаблонах на 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 ]

4 голосов
/ 17 октября 2011

TProductTableItemString, наследуя его, вызывает создание экземпляра TProductTableItem<char*>.В реализации TProductTableItem::LoadFromBuffer эта строка:

Value = buffer[Offset];

не может быть скомпилирована, поскольку буфер [Offset] является байтом, а Value является символом *.

Кстати, TProductTableItemString это не специализация, это просто наследование, а затем сокрытие LoadFromBuffer.Если вы действительно хотите специализироваться, вы должны написать:

template<>
class TProductTableItem<char*>
{
 ...
};
2 голосов
/ 17 октября 2011

Вы смешиваете два разных понятия: наследование и специализация шаблона.

Ваш класс не является специализацией шаблона, но он получает из шаблона создания. Однако этот шаблон не может быть создан, потому что когда 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) {
        ...
    }
};

Я сказал, может быть , потому что на самом деле мне не ясно, чего вы пытаетесь достичь.

1 голос
/ 17 октября 2011

Вы путаете понятия наследования и специализации.Во-первых, для того, чтобы специализировать шаблон, вы не наследуете его - вы используете этот синтаксис:

template <>
class TProductTableItem<char*>
{...}

Следующая путаница заключается в том, что вы пытаетесь использовать неспециализированные переменные-члены в специализации,Шаблонные специализации полностью отделены от неспециализированной версии.В этом примере вы объявили только переменные Offset, DataLength и Value внутри неспециализированного шаблона.Вам нужно добавить их в специализацию, если вы хотите, чтобы они там были:

template <>
class TProductTableItem<char*>
{
    int             Offset;
    int             DataLength;
    char*           Value;
    ...
}
0 голосов
/ 17 октября 2011

Вы хотите, чтобы ваша строка memcpy была более похожа на это:

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

И также, когда вы присваиваете значение:

    Value = (T)&buffer[Offset];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...