2011-10-16 15 views
0

私はC++でテンプレートを使い慣れていないので、ここに私の問題があります。ポインタテンプレートの特殊化

私は必要なものすべてを行うGenericクラスの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ではないように見えます。おかげさまで あなたはバリュー割り当てるとき

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

、同様に:あなたはあなたのmemcpyのラインがよりこのようになりたい

+0

バッファ[オフセット]は多くの(多くの!)方法で悪に見えます。あなたの問題はテンプレートの専門化とは関係がないと私は思っています。あなたはここで達成するために何を望んでいますか? – sehe

+0

@sehe:修正されました。しかし、あなたがこれを行う良い方法を持っているなら、私は;-)に入っています –

+2

あなたは質問を修正しませんでした。あなたはそのクラスで何をしようとしていますか?クラスとCスタイルのキャストをミックスしています。あなたはunitialized char *(Value)を使って書いています。あなたがバイナリシリアル化の貧弱なバージョンをやっているようです。これを[非XYの質問](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)にすると、質の高い回答が得られます – sehe

答えて

2

継承とテンプレートの特殊化という2つの異なる概念が混在しています。

クラスはテンプレートの特殊化ではありませんが、はテンプレートインスタンス化からを派生しています。ただし、T = char *ステートメントValue = buffer[offset];に型の不一致エラーがあるため、そのテンプレートをインスタンス化できません。あなたはテンプレートの特殊化を書きたい場合は、構文は2つのテンプレートのインスタンス化は、ビューの継承の観点から、一般的な無関係なタイプであることを

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) { 
     ... 
    } 
}; 

のようなものであるとなる場合があります。なぜなら、実際に達成しようとしていることがわからないからです。

+0

このようにすると、私の変数はもう知られていません...どうすれば修正できますか? –

+0

@ArnaudF:**いくつかのコードを追加しました**あなたが探しているものです – 6502

+0

異なる種類の変数にバッファをロードしようとしています。例:{0xFF、0x00}のバッファ16 bool(ブールごとに1ビット)と0x00 BYTEの値...(17 ProductTableItemに等しい) –

0

Value = (T)&buffer[Offset]; 
+0

はい私はそれを修正しましたが、コンパイルエラーを解決しません。 –

+0

実際には2つの問題がありました。 –

4

TProductTableItemStringが、それから継承することによって、TProductTableItem<char*>のインスタンス化の原因となります。 TProductTableItem::LoadFromBufferの実装では、この行:バッファため

Value = buffer[Offset]; 

をコンパイルすることができない[オフセット]はバイトであり、値は* CHARです。

ところで、TProductTableItemStringは特殊化されていません。それは単純に継承されてから、LoadFromBufferを隠しています。実際に専門化したい場合は、次のように記述する必要があります。

+0

同じようなコードを修正すると、私の(保護された)すべての変数にアクセスすることはできません... –

1

継承と特殊化の概念が混乱しています。まず、テンプレートを特化するためには、あなたはそれから派生していない - あなたはこの構文を使用します。

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

次の混乱は、あなたが専門で非専門のメンバ変数を使用しようとしているということです。テンプレートの特殊化は、特殊化されていないバージョンとは完全に別です。この例では、特殊テンプレート内に変数Offset,DataLengthおよびValueが宣言されています。これらを特殊化に追加する必要がある場合は、これらを特殊化に追加する必要があります。

関連する問題