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")?

1
  • out(&std::endl<char, std::char_traits<char>>); Commented Jan 2, 2014 at 13:33

1 Answer 1

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)

Sign up to request clarification or add additional context in comments.

8 Comments

The point is actually that it's a template, not that it's overloaded.
@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<T,Traits>) is an implementation detail that doesn't change the substrance about how an overload is choose.
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.
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
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)
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.