The following code gives an error when it's supposed to output just std::endl
:
#include <iostream>
#include <sstream>
struct MyStream {
std::ostream* out_;
MyStream(std::ostream* out) : out_(out) {}
std::ostream& operator<<(const std::string& s) {
(*out_) << s;
return *out_;
}
};
template<class OutputStream>
struct Foo {
OutputStream* out_;
Foo(OutputStream* out) : out_(out) {}
void test() {
(*out_) << "OK" << std::endl;
(*out_) << std::endl; // ERROR
}
};
int main(int argc, char** argv){
MyStream out(&std::cout);
Foo<MyStream> foo(&out);
foo.test();
return EXIT_SUCCESS;
}
The error is:
stream1.cpp:19: error: no match for 'operator<<' in '*((Foo<MyStream>*)this)->Foo<MyStream>::out_ << std::endl'
stream1.cpp:7: note: candidates are: std::ostream& MyStream::operator<<(const std::string&)
So it can output a string (see line above the error), but not just the std::endl
, presumably because std::endl
is not a string, but the operator<<
definition asks for a string.
Templating the operator<<
didn't help:
template<class T>
std::ostream& operator<<(const T& s) { ... }
How can I make the code work? Thanks!
You need to add this to your struct MyStream
:
std::ostream& operator<<( std::ostream& (*f)(std::ostream&) )
{
return f(*out_);
}
std::endl
is a function that appends a newline and flushes the underlying stream; this function signature accepts that function and applies it to the ostream
member.
Then, as a test, defining foo::test
as
void test() {
(*out_) << "start";
(*out_) << std::endl;
(*out_) << "done";
}
will correctly output
start done
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With