Ошибка компиляции в функции рекурсивного вариационного шаблона - PullRequest
8 голосов
/ 18 февраля 2011

Я подготовил простой шаблон теста с переменным значением в Code :: Blocks, но получаю ошибку:

Нет соответствующей функции для вызова функции «OutputSizes ()»

Вот мой исходный код:

#include <iostream>
#include <typeinfo>

using namespace std;

template <typename FirstDatatype, typename... DatatypeList>
void OutputSizes()
{
    std::cout << typeid(FirstDatatype).name() << ": " << sizeof(FirstDatatype) << std::endl;
    OutputSizes<DatatypeList...>();
}

int main()
{
    OutputSizes<char, int, long int>();
    return 0;
}

Я использую GNU GCC с -std=C++0x. Использование -std=gnu++0x не имеет значения.

Ответы [ 2 ]

14 голосов
/ 18 февраля 2011

Вот как вы устраняете неоднозначность базового варианта:

#include <iostream>
#include <typeinfo>

template <typename FirstDatatype>
void OutputSizes()
{
    std::cout << typeid(FirstDatatype).name() << ": " << sizeof(FirstDatatype) << std::endl;
}

template <typename FirstDatatype, typename SecondDatatype, typename... DatatypeList>
void OutputSizes()
{
    OutputSizes<FirstDatatype>()
    OutputSizes<SecondDatatype, DatatypeList...>();
}

int main()
{
    OutputSizes<char, int, long int>();
}
1 голос
/ 18 февраля 2011

Это потому, что вы не предоставили базовый вариант. Вы извлекли последний тип данных параметра шаблона переменной, а затем попытались сопоставить пустой параметр переменной функции, принимающей тип и параметр переменной. Необходимо указать «базовый случай», когда параметр переменной пуст.

using namespace std;

template <typename FirstDatatype, typename... DatatypeList>
void OutputSizes()
{
    std::cout << typeid(FirstDatatype).name() << ": " << sizeof(FirstDatatype) << std::endl;
    OutputSizes<DatatypeList...>();
}

template<typename... DataTypeList>
void OutputSizes() // We're called when there's no template arguments
                   // left in the pack
{
}

int main()
{
    OutputSizes<char, int, long int>();
    return 0;
}

Редактировать: Множественные нулевые перегрузки, которые я здесь показал, на самом деле работают, только когда вы берете фактические аргументы времени выполнения, тоже основанные на типах шаблонов. Если вы берете только параметры шаблона напрямую, вы должны использовать рекурсию два-один, как показано в ответе Говарда Хиннанта.

...