The immediate problem is that std::endl not an object, and the function template declares something like this:
template <typename cT, typename Traits> std::basic_ostream<cT, Traits>& endl(std::basic_ostream<cT, Traits>&);
To use a pointer to a function like this, you must output the template arguments. To this end, the class std::basic_ostream<cT, Traits> declared suitable overloads for operator<<() :
template <typename cT, typename Traits> std::basic_ostream<cT, Traits>& std::baisic_ostream<cT, Traits>::operator<< ( std::basic_ostream<cT, Traits>& (*manip)(std::basic_ostream<cT, Traits>&));
In this way, the compiler can infer the correct instance when the std::endl function is std::endl .
However, everything that is completely inappropriate, because what you are trying to do is better to do in a completely different way! You must create a suitable stream buffer and use the built std::ostream with this custom stream buffer. Below is a complete example of how to do this correctly (I published it earlier, but only a couple of dozen times ...):
#include <streambuf> struct teebuf : std::streambuf { std::streambuf* sb1_; std::streambuf* sb2_; teebuf(std::streambuf* sb1, std::streambuf* sb2) : sb1_(sb1), sb2_(sb2) { } int overflow(int c) { typedef std::streambuf::traits_type traits; bool rc(true); if (!traits::eq_int_type(traits::eof(), c)) { traits::eq_int_type(this->sb1_->sputc(c), traits::eof()) && (rc = false); traits::eq_int_type(this->sb2_->sputc(c), traits::eof()) && (rc = false); } return rc? traits::not_eof(c): traits::eof(); } int sync() { bool rc(true); this->sb1_->pubsync() != -1 || (rc = false); this->sb2_->pubsync() != -1 || (rc = false); return rc? 0: -1; } };
source share