2012-10-02 11 views
9

私は部分的な特殊化を行うことを試みています。私はtupleを持っています。特定の要素インデックスから最初のタプルインデックスまで繰り返し、tupleの各タイプの値を累積したいとします。これは、再帰的なテンプレートのインスタンス化を使用する単純な問題のようです。整数パラメータを使用したテンプレートの部分的な特殊化

問題は、再帰を機能させることができないようです。再帰を止めるには、タプル・インデックス0のテンプレート関数を部分的に特殊化する必要があります。それは十分単純だと思われますが、うまくいきません。

注:この例から実際のtupleのものは削除しました。これは無関係です。それは機能しないテンプレートの特殊化です。

template<int Index, typename Tpl> 
size_t CalcInterleaveByteOffset(const Tpl &t) 
{ 
    size_t prevOffset = CalcInterleaveByteOffset<Index - 1>(t); 
    return prevOffset + sizeof(Tpl); 
} 

template<typename Tpl> 
size_t CalcInterleaveByteOffset<0, Tpl>(const Tpl &t) 
{ 
    return 0; 
} 

GCC simply says that this kind of specialization is not allowed.これは本当ですか?このようなことを処理する他の方法がありますか?

答えて

11

原則として、部分テンプレートの特殊化のどのような形式も関数には使用できません。ただし、クラスは許可されています。だから、解決策は単純にあなたの関数をテンプレート付きホルダークラスの静的メンバーに移動することです。

テンプレート引数を推測する必要がある場合は、テンプレート化されたクラスを呼び出すラッパー関数を作成することができます。私は別のメンバー変数で、このように別のクラスを区別することができ

template<int Index, typename Tpl> 
class CalcInterleaveByteOffsetImpl 
{ 
    static size_t CalcInterleaveByteOffset(const Tpl &t) 
    { 
    // This is OK it calls the wrapper function 
    // You could also do 
    // size_t prevOffset = CalcInterleaveByteOffsetImpl<Index - 1, Tpl>::CalcInterleaveByteOffset(t); 
    size_t prevOffset = ::CalcInterleaveByteOffset<Index - 1>(t); 
    return prevOffset + sizeof(Tpl); 
    } 
}; 

template<typename Tpl> 
class CalcInterleaveByteOffsetImpl<0, Tpl> 
{ 
    static size_t CalcInterleaveByteOffset(const Tpl &t) 
    { 
    return 0; 
    } 
}; 

template<int Index, typename Tpl> 
size_t CalcInterleaveByteOffset(const Tpl &t) 
{ 
    return CalcInterlaveByteOffsetImpl<Index,Tpl>::CalcInterleaveByteOffset(t); 
} 
+0

結果はこのようなものでしょうか?はい、私は推測できますか? – GameDeveloper

関連する問題