Рекурсивная распаковка пакета шаблонов для функции без параметров
Я пытаюсь создать шаблон структуры с пакетом типов вариативного шаблона, который может вычесть сумму размеров всех переданных типов.
Ниже вы найдете упрощенный пример, в реальном контексте вычисленный размер используется для создания дополнительных объектов-членов.
template <typename... Types>
struct OverallSize
{
template <typename FirstType, typename... NextTypes>
static constexpr size_t sizesum() { return sizeof (FirstType) + sizesum<NextTypes...>(); }
template <typename LastType>
static constexpr size_t sizesum() { return sizeof (LastType); }
static constexpr size_t size = sizesum<Types...>();
};
// Should work e.g. like this
auto s = OverallSize<int, float, char>::size; // s will be 9 on x86-64
Я привык к этому рекурсивному подходу к распаковке параметров, когда дело доходит до списков аргументов, и предположил, что он также работает с функциями без аргументов и явной спецификацией шаблона. Однако я получаю следующую ошибку при компиляции с помощью clang
Call to 'sizesum' is ambiguous
...
Candidate function [with FirstType = unsigned long, NextTypes = <>]
Candidate function [with LastType = unsigned long]
Таким образом, кажется, что последняя итерация рекурсии здесь не работает - не уверен, почему компилятор просто не выбрал наиболее очевидный выбор: тот, у которого есть только один тип шаблона - так же, как это произошло бы, если бы существовал фактический аргумент шаблона передается в функцию.
Итак, что мне нужно сделать, чтобы эта компиляция и работала должным образом?
1 ответ
Для C++14 вы можете использовать SFINAE:
template <
typename FirstType,
typename... NextTypes,
std::enable_if_t<sizeof...(NextTypes) >= 1>* = nullptr >
static constexpr size_t sizesum() {
return sizeof (FirstType) + sizesum<NextTypes...>();
}
этот шаблон будет рассматриваться только в том случае, если размер пакета параметров>= 1.