2014-01-02 4 views
0

Код:VARIADIC шаблон не компилируется

#include <iostream> 

template<typename T>  
void out()     // line 4 
{ 
} 

template<typename T, typename... Args> 
void out(T value, Args... args)  // line 9 
{ 
    std::cout << value; 
    out(args...); // line 12 
} 

int main() 
{ 
    out("12345", std::endl); // line 17 
    return 0; 
} 

Строят ошибки:

g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++11 -pthread -MMD -MP -MF"main.d" -MT"main.d" -o "main.o" "../main.cpp" 
../main.cpp: In function ‘int main()’: 
../main.cpp:17:24: error: no matching function for call to ‘out(const char [6], <unresolved overloaded function type>)’ 
../main.cpp:17:24: note: candidates are: 
../main.cpp:4:6: note: template<class T> void out() 
../main.cpp:4:6: note: template argument deduction/substitution failed: 
../main.cpp:17:24: note: candidate expects 0 arguments, 2 provided 
../main.cpp:9:6: note: void out(T, Args ...) [with T = const char*; Args = {}] 
../main.cpp:9:6: note: candidate expects 1 argument, 2 provided 

Я хочу, чтобы эта программа, чтобы дать тот же результат, как std::cout << "12345" << std::endl; Что плохого в функции шаблона?

+0

Вам не хватает '.' в инструкции для распаковки. Измените его на 'args ...'. – legends2k

+0

Редактирование вопроса, есть еще сообщения с ... –

+0

@AlexFarber Мои извинения ... – 0x499602D2

ответ

6

Проблема заключается в том, что вы не создали аргумент без аргумента out и его нельзя вызвать без явной подачи аргументов шаблона. Таким образом,

void out() {} 

template<typename T, typename... Args> 
void out(T value, Args... args) { 
    std::cout << value; 
    out(args...); 
} 

int main() { 
    out(1, 2.0, "3"); 
    return 0; 
} 

работает по назначению.

+0

Слова, которые вы искали, это «аргумент типа-вычет». – sehe

3

Существует синтаксическая ошибка (пропуская .), что заставляет компилятор сходить с ума.

После этого, вы можете иметь проблемы с out("12345", std::endl) вызова, будучи std::endl переопределенная функция, компилятор не может выбрать из (только бросить его как static_cast<std::ostream&(*)(std::ostream&)>(std::endl))

Кроме того, рекурсия в out заканчивается out() вызова , но нет выхода с 0 параметрами. (см. также yuri answer: https://stackoverflow.com/a/20879525/924727)

+0

Спасибо. '..' была опечатана, исправлена. Удаление 'std :: endl' из вызова не помогает, проблема в самом шаблоне, я думаю. –

+0

После удаления первой строки 'template' она выглядит лучше. Вы правы, 'std :: endl' не компилируется. Но ваш кастинг не работает: 'invalid static_cast from type '<неразрешенный перегруженный тип функции>' для ввода 'std :: ostream & (std :: ostream &) {aka std :: basic_ostream & (std :: basic_ostream &)} ' –

+0

OOPS: см. Редактирование (забыли' (*) ') –

Смежные вопросы