The return type of << can be anything you want - just create your own type. The only real restriction is that the ostringstream code must work. Support for endl and other manipulators is trivial. Check this out:
#include <iostream>
#include <sstream>
#include <iomanip>
struct MyStream
{
mutable std::ostringstream ss;
MyStream() {}
MyStream(std::ostringstream & oss) { ss << oss.str(); }
};
typedef std::ostream & (*manipulator_t) (std::ostream &);
const MyStream & operator << (const MyStream & s, manipulator_t m)
{
s.ss << m;
return s;
}
template <class T>
const MyStream & operator << (const MyStream & s, T v)
{
s.ss << v;
return s;
}
void MyPrint(const MyStream & s)
{
std::cout << "logged: " << s.ss.str();
}
int main()
{
MyPrint(MyStream() << "true && false == " << std::boolalpha << (true && false) << std::endl);
std::ostringstream oss;
oss << std::setw(22) << "Hello, World!" << std::endl;
MyPrint(oss);
}
Online demo -> http://ideone.com/Gm7Cnc