I’m trying to make a C++ class resembling std::ostream, that will take its input and write to two std::ostreams given in the constructor. Here it is together with appropriate operator<< template:
struct SplitStream
{
SplitStream(std::ostream & a_, std::ostream & b_) : a(a_), b(b_) {}
std::ostream & a, & b;
};
template<class T>
const SplitStream & operator << (const SplitStream & sp, const T & x)
{
sp.a << x;
sp.b << x;
return sp;
}
Several lines below that code, I try to use this class:
void foo(SplitStream & out)
{
double some_double = 1.23;
out << "bar" << some_double << std::endl;
}
And I get this rather enigmatic error:
... error C2678: binary '<<' : no operator found which takes a left-hand operand of type 'const SplitStream' (or there is no acceptable conversion) ...
What am I doing wrong? I tried to define operator<< without consts, and it didn’t compile either.
The immediate problem is that
std::endlisn’t an object but a function template declared something like this:To use a function pointer like this, the template arguments need to be deduced. To this end, the class
std::basic_ostream<cT, Traits>declared suitable overloads foroperator<<():This way, the compiler can deduce the correct instantiation when the
std::endlfunction is referenced.However, all that is utterly irrelevant because what you are trying to do is better done entirely differently! You should create a suitable stream buffer and use a reasonably constructed
std::ostreamwith this custom stream buffer. Below is a complete example how to do it properly (I had posted it before but only a couple dozens times…):