具有整数参数的模板的部分特化

发布于 2025-01-14 13:23:10 字数 641 浏览 2 评论 0原文

我正在尝试做一些部分专业化的事情。我有一个元组,我想从某个元素索引迭代到第一个元组索引,累积元组中每种类型的值。这似乎是使用递归模板实例化的简单问题。

问题是,我似乎无法让递归工作。为了停止递归,我需要部分特化元组索引 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 只是说不允许这种专业化。 这是真的吗?还有其他方法来处理这种事情吗?

I'm trying to do some partial specialization stuff. I have a tuple, and I want to iterate from a certain element index to the first tuple index, accumulating a value from each type in the tuple. This would seem to be a simple matter of using a recursive template instantiation.

The problem is, I can't seem to get the recursion to work. In order to stop the recursion, I need to partially specialize the template function at tuple index 0. That seemed simple enough, but it's not working.

Note: I've removed the actual tuple stuff from the example, as it's irrelevant; it's the template specialization that's not working.

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. Is that true? Is there some other way to handle this sort of thing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

叹梦 2025-01-21 13:23:10

通常,函数不允许任何形式的部分模板专门化。但是,上课是允许的。因此,解决方案只是将函数移动到模板化持有者类的静态成员中。

如果您需要推导模板参数,则只需创建一个调用模板化类的包装函数即可。

结果是这样的:

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

As a rule any form of partial template specialisation is not allowed for functions. However it is allowed for classes. So the solution is simply to move your function to a static member of a templated holder class.

If you need to deduce the template arguments, you can then just create a wrapper function that calls the templated class.

The result is something like this:

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文