Ошибка компиляции в функции рекурсивного вариационного шаблона
Я подготовил простой шаблонный тест с переменным кодом в 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 ответа
Вот как вы устраняете неоднозначность базового варианта:
#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>();
}
Это потому, что вы не предоставили базовый случай. Вы извлекли последний тип данных параметра шаблона переменной, а затем попытались сопоставить пустой параметр переменной функции, принимающей тип и параметр переменной. Вам необходимо указать "базовый случай", когда параметр переменной пуст.
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;
}
Изменить: перегрузки с многими нулями, которые я показал здесь, на самом деле работают, только когда вы берете фактические аргументы времени выполнения, слишком основанные на типах шаблонов. Если вы берете только параметры шаблона напрямую, вы должны использовать рекурсию два-один, как показано в ответе Говарда Хиннанта.