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 回答