Частичная специализация шаблонов с целочисленными параметрами

Я пытаюсь сделать некоторые вещи частичной специализации. у меня есть 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 просто говорит, что такая специализация не допускается. Это правда? Есть ли другой способ справиться с подобными вещами?

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

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]