Рекурсивная распаковка пакета шаблонов для функции без параметров - PullRequest
0 голосов
/ 22 апреля 2020

Я пытаюсь создать шаблон структуры с помощью пакета типов шаблона variadi c, который может вычесть сумму размера всех передаваемых типов.

Ниже вы найдете упрощенный пример, приведенный в в реальном контексте вычисленный размер используется для создания дополнительных объектов-членов.

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 Ответ

1 голос
/ 22 апреля 2020

Для 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.

Демо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...