So, I was trying to write a function like this:
void append_to_stream(std::ostream &stream) { } template <typename T, typename... Args> void append_to_stream(std::ostream &stream, T first, Args&&... rest) { stream << first; append_to_stream(stream, rest...); } and call it like:
append_to_stream(stream, std::endl, std::endl); But this doesn't work. I get an error that says 'too many arguments' to the function. I've narrowed it down to the point I know that the std::endl is guilty - probably because it's a function. I managed to 'solve' this by declaring a struct called endl and define the <<operator for it so that it simply calls std::endl. This works but doesn't feel particularly good. Is it not possible to accept std::endl as a template argument? The function works for other types.
Edit: here's the error:
src/log/sinks/file_sink.cpp:62:21: error: too many arguments to function ‘void log::sinks::append_to_stream(std::string&, Args&& ...) [with Args = {}, std::string = std::basic_string<char>]’ Update
Trying to get the compiler to deduce the correct template arguments @MooingDuck suggested that a function of the following form could be used:
template<class e, class t, class a> basic_ostream<e,t>&(*)(basic_ostream<e,t>&os) get_endl(basic_string<e,t,a>& s) { return std::endl<e,t>; } However, this doesn't compile.
Error:
src/log/sinks/file_sink.cpp:42:28: error: expected unqualified-id before ‘)’ token src/log/sinks/file_sink.cpp:42:53: error: expected initializer before ‘get_endl’ Any ideas why? For the sake of compiling this, I've added using namespace std;
std::endlisn't a function, it is a template.std::string? That doesn't match anything you said...endl, which form a set of overloaded functions. Since the function argument type is generic, then any of these would match, and the compiler can't choose from them. If the argument had a specific type (likeostream&(*)(ostream&)), then the compiler could pick the specialisation (endl<char, char_traits<char>>) that has that type; that's whyostream << endlis valid.std::stringargument in. The real function is wrapped by a function that creates anfstream.