I usually implement the output operator for a class, operator<<().
I find it useful for debugging and regression testing purposes.
Occasionally when defining a class hierarchy with polymorphism in mind
I’ll instead define a virtual print() method.
Base base; std::cout << "base = " << base << std::endl;
Here’s the typical implementation:
class Base {
// ...
public:
/// print Base with flags indicating hw much extra to include
virtual void print (std::ostream &out, int flags);
};
std::ostream &
operator<< (std::ostream &out, const Base &base)
{
base.print (out, 0);
}
So everything is great except… I now want to pass that extra
argument. I could write the following ugly code:
std::cout << "base = "; base.print (std::cout, 1); std::cout << std::endl;
Instead, I’m going to follow the example from <iomanip> and define a struct
that saves the arguments and then define an output operator for that
struct. The following code makes it so you can write the above as:
std::cout << "base = " << printstream (base, 1) << std::endl;
Here is the implementation of that. This expects the class to implement a method print() that takes a std::ostream and a second argument. It’s pretty easy to extend this to a print() that takes a third argument.
#ifndef INCLUDED_PRINTSTREAM_H
#define INCLUDED_PRINTSTREAM_H
#include
namespace printstream_impl {
template
struct PrintStream1
{
const ObjectType & m_object;
const Arg1Type & m_arg1;
PrintStream1 (const ObjectType &object, const Arg1Type &arg1)
: m_object (object),
m_arg1 (arg1)
{
}
std::ostream &print (std::ostream &out) const
{
m_object.print (out, m_arg1);
return out;
}
};
template
std::ostream &operator<<(std::ostream &out, const PrintStream1 &ps)
{
ps.print (out);
return out;
}
} // End namespace printstream
template
printstream_impl::PrintStream1
printstream (const ObjectType &object,
const Arg1Type &arg1)
{
return printstream_impl::PrintStream1 (object, arg1);
}
#endif /* INCLUDED_PRINTSTREAM_H */