0

Code:

#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;
}

Build errors:

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

I want this program to give the same result as std::cout << "12345" << std::endl; What is wrong in the template function?

Alex F
  • 42,307
  • 41
  • 144
  • 212

2 Answers2

6

The problem is that you made your no argument version of out be a template, and it cannot be called without explicitly supplying template arguments. Thus

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;
}

works as intended.

yuri kilochek
  • 12,709
  • 2
  • 32
  • 59
3

There is a syntax error (a missning .) that makes the compiler go crazy.

After that, you may also have a problem with the out("12345", std::endl) call, being std::endl an overridden function that compiler cannot choose from (just cast it as static_cast<std::ostream&(*)(std::ostream&)>(std::endl))

Also, the recursion in out ends in a out() call, but there is no out with 0 parameters.(see also yuri answer: https://stackoverflow.com/a/20879525/924727 )

Community
  • 1
  • 1
Emilio Garavaglia
  • 20,229
  • 2
  • 46
  • 63
  • Thanks. `..` was typo, fixed. Removing `std::endl` from the call doesn't help, the problem is in template itself, I guess. – Alex F Jan 02 '14 at 08:53
  • After removing the first `template` line it looks better. You are right, `std::endl` is not compiled. But your casting is not working: `invalid static_cast from type ‘’ to type ‘std::ostream&(std::ostream&) {aka std::basic_ostream&(std::basic_ostream&)}` – Alex F Jan 02 '14 at 09:05
  • OOPS: see the edit (forgot a `(*)` ) – Emilio Garavaglia Jan 02 '14 at 09:11
  • Thanks. I posted another question http://stackoverflow.com/questions/20879611/stdendl-and-variadic-template Write the answer there. – Alex F Jan 02 '14 at 09:13