10

Code:

#include <iostream>

void out()
{
}

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

int main()
{
    out("12345", "  ", 5, "\n"); // OK
    out(std::endl);              // compilation error
    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:15: error: no matching function for call to ‘out(<unresolved overloaded function type>)’
../main.cpp:17:15: note: candidates are:
../main.cpp:3:6: note: void out()
../main.cpp:3:6: note:   candidate expects 0 arguments, 1 provided
../main.cpp:8:6: note: template<class T, class ... Args> void out(T, Args ...)
../main.cpp:8:6: note:   template argument deduction/substitution failed:
../main.cpp:17:15: note:   couldn't deduce template parameter ‘T’

So, everything is OK except std::endl. How can I fix this (except of using "\n")?

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
Alex F
  • 42,307
  • 41
  • 144
  • 212

1 Answers1

12

std::endl is an overloaded function, (in many STL implementations, a template) and the compiler has no info about what to choose from.

Just cast it as static_cast<std::ostream&(*)(std::ostream&)>(std::endl)

Emilio Garavaglia
  • 20,229
  • 2
  • 46
  • 63
  • 3
    The point is actually that it's a template, not that it's overloaded. – jogojapan Jan 02 '14 at 09:23
  • 1
    @jogojapan: a template is technically a "generator of overloads": there are as many `std::endl` as stream classes. Whether this is obtained by declaring some of them (for ostream, and wostream for example) or a template (on `ostream`) is an implementation detail that doesn't change the substrance about how an overload is choose. – Emilio Garavaglia Jan 02 '14 at 09:29
  • For the effectiveness of your solution it makes no difference, but template instantiation and overload resolution are two very different mechanisms. Calling a template a generator of overloads is misleading. – jogojapan Jan 02 '14 at 09:33
  • @jogojapan: your nitpicking in this contect has no sense. They are different mechanism, but the context is about what they produce (a set of homonimous functions). Whether `std::endl` is a set of overloads or a template, you always have an overload set. And you cannot know what it actually is, since it depends on how the STL is implemented (and different implementation are around, using both methods) – Emilio Garavaglia Jan 02 '14 at 09:40
  • 1
    The way you describe this, a template generates a set of functions and then applies overload resolution to choose one. That is incorrect, for two reasons: a) In the case of simple overload resolution, the set of functions to choose from is predefined, and implicit type conversion is the only mechanism the compiler can use to find a match between the given arguments and the function it chooses, whereas in the case of template instantiation, a new instance of the function can be generated to fit the given arguments exactly. This has wide implications in ambiguous situations. b) In the case of – jogojapan Jan 02 '14 at 09:50
  • [cont'd] template instantiation, ambiguities can also exist at the level of the template definition (like in [this question](http://stackoverflow.com/questions/17313649/how-can-i-distinguish-overloads-of-templates-with-non-type-parameters)), and then the special mechanism of partial ordering [which works completely differently than overload resolution] is applied, often producing surprising results. Asking you to use terminology correctly to avoid misunderstandings is a reasonable request, even if the potential misunderstandings have no direct implications for the validity of your code. – jogojapan Jan 02 '14 at 09:52
  • 1
    If `std::endl` is a set of overloads, the library implementation has a bug since it's unusable with custom character traits (or custom character types) – Cubbi Jan 02 '14 at 15:09
  • Is there a way to do it using C++17 features? – Jive Dadson Nov 09 '17 at 16:13