14

私はいくつかの部分的な専門化をしようとしています。があり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 は、この種の特殊化は許可されていないと単純に述べています。本当?この種のことを処理する他の方法はありますか?

4

1 に答える 1

15

原則として、部分的なテンプレートの特殊化の形式は、関数には許可されていません。ただし、クラスについては許可されています。したがって、解決策は、関数をテンプレート化されたホルダー クラスの静的メンバーに移動するだけです。

テンプレート引数を推測する必要がある場合は、テンプレート化されたクラスを呼び出すラッパー関数を作成するだけです。

結果は次のようになります。

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);
}
于 2012-10-02T01:05:18.587 に答える