Я пытаюсь сделать некоторые вещи частичной специализации. у меня есть 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 просто говорит, что такая специализация не допускается. Это правда? Есть ли другой способ справиться с подобными вещами?
Как правило, любая форма частичной специализации шаблона не допускается для функций. Однако это разрешено для занятий. Таким образом, решение состоит в том, чтобы просто переместить вашу функцию в статический член класса шаблонного держателя.
Если вам нужно вывести аргументы шаблона, вы можете просто создать функцию-оболочку, которая вызывает шаблонный класс.
Результат примерно такой:
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);
}
Других решений пока нет …