C++ Decorate basic_iostream classes - c++

I want to do something like the following code shows:
class foo
{
private:
std::fstream* m_stream;
public:
foo(std::fstream* stream) : m_stream(stream) { }
foo& write(char const* s, std::streamsize count)
{
if (/*condition*/)
{
m_stream->write(s, count);
}
else
{
// ...
}
return *this;
}
foo& read(char* s, std::streamsize count)
{
if (/*condition*/)
{
m_stream->read(s, count);
}
else
{
// ...
}
return *this;
}
};
I would need to add the same behavior to all similar methods (e.g. put). This shouldn't be applied to file streams only, but all other stream classes. Is there any easy way to allow these functionality?

Many of the formatted output operators (operator<<) write directly to the underlying stream buffer. What you need to do in order to accomplish this in a general fashion is derive a class from std::basic_streambuf that forwards all data to another std::basic_streambuf, and then optionally create a minimal std::basic_ostream implementation to make using your stream buffer easier.
I wouldn't say this is particularly easy, though, but it's the only way to do this in a way that can affect all stream types.
Here is an example of a minimal stream buffer that forwards to another stream buffer (and performs some meaningless transformation just to demonstrate what you can do), and an accompanying stream:
#include <iostream>
#include <streambuf>
template<typename CharType, typename Traits = std::char_traits<CharType> >
class ForwardingStreamBuf : public std::basic_streambuf<CharType, Traits>
{
public:
typedef Traits traits_type;
typedef typename traits_type::int_type int_type;
typedef typename traits_type::pos_type pos_type;
typedef typename traits_type::off_type off_type;
ForwardingStreamBuf(std::basic_streambuf<CharType, Traits> *baseStreamBuf)
: _baseStreamBuf(baseStreamBuf)
{
}
protected:
virtual int_type overflow(int_type c = traits_type::eof())
{
if( _baseStreamBuf == NULL )
return traits_type::eof();
if( traits_type::eq_int_type(c, traits_type::eof()) )
return traits_type::not_eof(c);
else
{
CharType ch = traits_type::to_char_type(c);
if( ch >= 'A' && ch <= 'z' )
ch++; // Do some meaningless transformation
return _baseStreamBuf->sputc(ch);
}
}
virtual int sync()
{
if( _baseStreamBuf == NULL )
return -1;
else
return _baseStreamBuf->pubsync();
}
private:
std::basic_streambuf<CharType, Traits> *_baseStreamBuf;
};
template<typename CharType, typename Traits = std::char_traits<CharType> >
class ForwardingStream : public std::basic_ostream<CharType, Traits>
{
public:
ForwardingStream(std::basic_ostream<CharType, Traits> &stream)
: std::basic_ostream<CharType, Traits>(NULL), _buffer(stream.rdbuf())
{
this->init(&_buffer);
}
ForwardingStreamBuf<CharType, Traits>* rdbuf() const
{
return &_buffer;
}
private:
ForwardingStreamBuf<CharType, Traits> _buffer;
};
This can be used very simply:
int main()
{
ForwardingStream<char> test(std::cout);
test << "Foo" << std::endl;
}
Which would output Gpp. I hope that helps you on your way.

Something like this?
template <class Stream>
class DecoratedStream {
public:
DecoratedStream(Stream* stream) : m_stream(stream) {}
DecoratedStream& write(const char* data, int count) {
m_stream->write(data, count);
}
};

If I understand you correctly, you want to decorate methods of any iostream. So just make your decorator take an iostream as decoratee (as opposed to an fstream, which is a subclass of iostream).

Having pointer inside a structure as your current approach is dangerous and error prone. Instead just derive such stream classes and implement basic constructors and wrap around your custom methods such as write().
template<typename StreamType>
class foo : StreamType
{
// wrapper constructors supporting StreamType() constructors
foo& write(char const* s, std::streamsize count)
{
//...
return *this;
}
};
Usage:
foo<fstream> obj;
obj.write(...);

The usual solution for this sort of problem is to use templates. There
aren't that many functions in an std::istream or and std::ostream
which need covering, and a good template member for<<and>>should
cover a lot of the cases. In most of the cases I've done this, I've
only offerred<<or>>`. (Generally speaking, I've not needed
bidirectional streams.)
As for handling other types of streams, just use std::iostream instead
of std::fstream. (In general, except when opening files, you
shouldn't see the fstream part.)

Related

How to encapsulate two stream buffers

std::cout.rdbuf() is so easy to use. But I wish to print string to console as well as write it to a file.
So what I am thinking of is to encapsulate two stream buffers into a derived class of std::streambuf, and pass this to rdbuf(). Is that possible?
How should I accomplish that?
I think a better way to do this would be to encapsulate two streams into an actual stream class derived from std::basic_ostream<...>.
Something for a start would be:
template<class charT, class traits = std::char_traits<charT>>
class basic_binary_stream : public std::basic_osteam<charT>
{
typedef std::basic_ostream<charT> stream_type;
typedef std::char_traits<charT> traits_type;
/* ... */
public:
binary_stream(stream_type& o1, stream_type& o2)
: s1(o1), s2(o2)
{ }
binary_stream& operator<<(int n)
{
s1 << n;
s2 << n;
return *this;
}
/* ... */
private:
stream_type& s1, &s2;
};
using binary_stream = basic_binary_stream<char>;

Building boost::options from a string/boost::any map

I have a map which represents a configuration. It's a map of std::string and boost::any.
This map is initialized at the start and I'd like the user to be able to override these options on the command line.
What I'd love to do is build the program options from this map using the options_description::add_option() method. However, it takes a template argument po::value<> whereas all I have is boost::any.
So far, I just have the shell of the code. m_Config represents my configuration class, and getTuples() returns a std::map<std::string, Tuple>. TuplePair is a typedef of std::pair<std::string, Tuple> and the Tuple contains the boost::any I am interested in.
po::options_description desc;
std::for_each(m_Config.getTuples().begin(),
m_Config.getTuples().end(),
[&desc](const TuplePair& _pair)
{
// what goes here? :)
// desc.add_options() ( _pair.first, po::value<???>, "");
});
Is there a way to build it this way, or do I need to resort to doing it myself?
Thanks in advance!
boost::any is not applicable to your problem. It performs the most basic form of type erasure: storage and (type-safe) retrieval, and that's it. As you've seen, no other operations can be performed. As jhasse points out, you could just test every type you want to support, but this is a maintenance nightmare.
Better would be to expand upon the idea boost::any uses. Unfortunately this requires a bit of boiler-plate code. If you'd like to try it, there's a new Boost library being discussed right now on the mailing list (titled "[boost] RFC: type erasure") that is essentially a generalized type erasure utility: you define the operations you'd like your erased type to support, and it generates the proper utility type. (It can simulate boost::any, for example, by requiring the erased type be copy-constructible and type-safe, and can simulate boost::function<> by additionally requiring the type be callable.)
Aside from that, though, your best option is probably to write such a type yourself. I'll do it for you:
#include <boost/program_options.hpp>
#include <typeinfo>
#include <stdexcept>
namespace po = boost::program_options;
class any_option
{
public:
any_option() :
mContent(0) // no content
{}
template <typename T>
any_option(const T& value) :
mContent(new holder<T>(value))
{
// above is where the erasure happens,
// holder<T> inherits from our non-template
// base class, which will make virtual calls
// to the actual implementation; see below
}
any_option(const any_option& other) :
mContent(other.empty() ? 0 : other.mContent->clone())
{
// note we need an explicit clone method to copy,
// since with an erased type it's impossible
}
any_option& operator=(any_option other)
{
// copy-and-swap idiom is short and sweet
swap(*this, other);
return *this;
}
~any_option()
{
// delete our content when we're done
delete mContent;
}
bool empty() const
{
return !mContent;
}
friend void swap(any_option& first, any_option& second)
{
std::swap(first.mContent, second.mContent);
}
// now we define the interface we'd like to support through erasure:
// getting the data out if we know the type will be useful,
// just like boost::any. (defined as friend free-function)
template <typename T>
friend T* any_option_cast(any_option*);
// and the ability to query the type
const std::type_info& type() const
{
return mContent->type(); // call actual function
}
// we also want to be able to call options_description::add_option(),
// so we add a function that will do so (through a virtual call)
void add_option(po::options_description desc, const char* name)
{
mContent->add_option(desc, name); // call actual function
}
private:
// done with the interface, now we define the non-template base class,
// which has virtual functions where we need type-erased functionality
class placeholder
{
public:
virtual ~placeholder()
{
// allow deletion through base with virtual destructor
}
// the interface needed to support any_option operations:
// need to be able to clone the stored value
virtual placeholder* clone() const = 0;
// need to be able to test the stored type, for safe casts
virtual const std::type_info& type() const = 0;
// and need to be able to perform add_option with type info
virtual void add_option(po::options_description desc,
const char* name) = 0;
};
// and the template derived class, which will support the interface
template <typename T>
class holder : public placeholder
{
public:
holder(const T& value) :
mValue(value)
{}
// implement the required interface:
placeholder* clone() const
{
return new holder<T>(mValue);
}
const std::type_info& type() const
{
return typeid(mValue);
}
void add_option(po::options_description desc, const char* name)
{
desc.add_options()(name, po::value<T>(), "");
}
// finally, we have a direct value accessor
T& value()
{
return mValue;
}
private:
T mValue;
// noncopyable, use cloning interface
holder(const holder&);
holder& operator=(const holder&);
};
// finally, we store a pointer to the base class
placeholder* mContent;
};
class bad_any_option_cast :
public std::bad_cast
{
public:
const char* what() const throw()
{
return "bad_any_option_cast: failed conversion";
}
};
template <typename T>
T* any_option_cast(any_option* anyOption)
{
typedef any_option::holder<T> holder;
return anyOption.type() == typeid(T) ?
&static_cast<holder*>(anyOption.mContent)->value() : 0;
}
template <typename T>
const T* any_option_cast(const any_option* anyOption)
{
// none of the operations in non-const any_option_cast
// are mutating, so this is safe and simple (constness
// is restored to the return value automatically)
return any_option_cast<T>(const_cast<any_option*>(anyOption));
}
template <typename T>
T& any_option_cast(any_option& anyOption)
{
T* result = any_option_cast(&anyOption);
if (!result)
throw bad_any_option_cast();
return *result;
}
template <typename T>
const T& any_option_cast(const any_option& anyOption)
{
return any_option_cast<T>(const_cast<any_option&>(anyOption));
}
// NOTE: My casting operator has slightly different use than
// that of boost::any. Namely, it automatically returns a reference
// to the stored value, so you don't need to (and cannot) specify it.
// If you liked the old way, feel free to peek into their source.
#include <boost/foreach.hpp>
#include <map>
int main()
{
// (it's a good exercise to step through this with
// a debugger to see how it all comes together)
typedef std::map<std::string, any_option> map_type;
typedef map_type::value_type pair_type;
map_type m;
m.insert(std::make_pair("int", any_option(5)));
m.insert(std::make_pair("double", any_option(3.14)));
po::options_description desc;
BOOST_FOREACH(pair_type& pair, m)
{
pair.second.add_option(desc, pair.first.c_str());
}
// etc.
}
Let me know if something is unclear. :)
template<class T>
bool any_is(const boost::any& a)
{
try
{
boost::any_cast<const T&>(a);
return true;
}
catch(boost::bad_any_cast&)
{
return false;
}
}
// ...
po::options_description desc;
std::for_each(m_Config.getTuples().begin(),
m_Config.getTuples().end(),
[&desc](const TuplePair& _pair)
{
if(any_is<int>(_pair.first))
{
desc.add_options() { _pair.first, po::value<int>, ""};
}
else if(any_is<std::string>(_pair.first))
{
desc.add_options() { _pair.first, po::value<std::string>, ""};
}
else
{
// ...
}
});
// ...
If you have more than a handful of types consider using typelists.

OneOfAType container -- storing one each of a given type in a container -- am I off base here?

I've got an interesting problem that's cropped up in a sort of pass based compiler of mine. Each pass knows nothing of other passes, and a common object is passed down the chain as it goes, following the chain of command pattern.
The object that is being passed along is a reference to a file.
Now, during one of the stages, one might wish to associate a large chunk of data, such as that file's SHA512 hash, which requires a reasonable amount of time to compute. However, since that chunk of data is only used in that specific case, I don't want all file references to need to reserve space for that SHA512. However, I also don't want other passes to have to recalculate the SHA512 hash over and over again. For example, someone might only accept files which match a given list of SHA512s, but they don't want that value printed when the file reference gets to the end of the chain, or perhaps they want both, or... .etc.
What I need is some sort of container which contain only one of a given type. If the container does not contain that type, it needs to create an instance of that type and store it somehow. It's basically a dictionary with the type being the thing used to look things up.
Here's what I've gotten so far, the relevant bit being the FileData::Get<t> method:
class FileData;
// Cache entry interface
struct FileDataCacheEntry
{
virtual void Initalize(FileData&)
{
}
virtual ~FileDataCacheEntry()
{
}
};
// Cache itself
class FileData
{
struct Entry
{
std::size_t identifier;
FileDataCacheEntry * data;
Entry(FileDataCacheEntry *dataToStore, std::size_t id)
: data(dataToStore), identifier(id)
{
}
std::size_t GetIdentifier() const
{
return identifier;
}
void DeleteData()
{
delete data;
}
};
WindowsApi::ReferenceCounter refCount;
std::wstring fileName_;
std::vector<Entry> cache;
public:
FileData(const std::wstring& fileName) : fileName_(fileName)
{
}
~FileData()
{
if (refCount.IsLastObject())
for_each(cache.begin(), cache.end(), std::mem_fun_ref(&Entry::DeleteData));
}
const std::wstring& GetFileName() const
{
return fileName_;
}
//RELEVANT METHOD HERE
template<typename T>
T& Get()
{
std::vector<Entry>::iterator foundItem =
std::find_if(cache.begin(), cache.end(), boost::bind(
std::equal_to<std::size_t>(), boost::bind(&Entry::GetIdentifier, _1), T::TypeId));
if (foundItem == cache.end())
{
std::auto_ptr<T> newCacheEntry(new T);
Entry toInsert(newCacheEntry.get(), T::TypeId);
cache.push_back(toInsert);
newCacheEntry.release();
T& result = *static_cast<T*>(cache.back().data);
result.Initalize(*this);
return result;
}
else
{
return *static_cast<T*>(foundItem->data);
}
}
};
// Example item you'd put in cache
class FileBasicData : public FileDataCacheEntry
{
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
unsigned __int64 size;
public:
enum
{
TypeId = 42
}
virtual void Initialize(FileData& input)
{
// Get file attributes and friends...
}
DWORD GetAttributes() const;
bool IsArchive() const;
bool IsCompressed() const;
bool IsDevice() const;
// More methods here
};
int main()
{
// Example use
FileData fd;
FileBasicData& data = fd.Get<FileBasicData>();
// etc
}
For some reason though, this design feels wrong to me, namely because it's doing a whole bunch of things with untyped pointers. Am I severely off base here? Are there preexisting libraries (boost or otherwise) which would make this clearer/easier to understand?
As ergosys said already, std::map is the obvious solution to your problem. But I can see you concerns with RTTI (and the associated bloat). As a matter of fact, an "any" value container does not need RTTI to work. It is sufficient to provide a mapping between a type and an unique identifier. Here is a simple class that provides this mapping:
#include <stdexcept>
#include <boost/shared_ptr.hpp>
class typeinfo
{
private:
typeinfo(const typeinfo&);
void operator = (const typeinfo&);
protected:
typeinfo(){}
public:
bool operator != (const typeinfo &o) const { return this != &o; }
bool operator == (const typeinfo &o) const { return this == &o; }
template<class T>
static const typeinfo & get()
{
static struct _ti : public typeinfo {} _inst;
return _inst;
}
};
typeinfo::get<T>() returns a reference to a simple, stateless singleton which allows comparisions.
This singleton is created only for types T where typeinfo::get< T >() is issued anywhere in the program.
Now we are using this to implement a top type we call value. value is a holder for a value_box which actually contains the data:
class value_box
{
public:
// returns the typeinfo of the most derived object
virtual const typeinfo& type() const =0;
virtual ~value_box(){}
};
template<class T>
class value_box_impl : public value_box
{
private:
friend class value;
T m_val;
value_box_impl(const T &t) : m_val(t) {}
virtual const typeinfo& type() const
{
return typeinfo::get< T >();
}
};
// specialization for void.
template<>
class value_box_impl<void> : public value_box
{
private:
friend class value_box;
virtual const typeinfo& type() const
{
return typeinfo::get< void >();
}
// This is an optimization to avoid heap pressure for the
// allocation of stateless value_box_impl<void> instances:
void* operator new(size_t)
{
static value_box_impl<void> inst;
return &inst;
}
void operator delete(void* d)
{
}
};
Here's the bad_value_cast exception:
class bad_value_cast : public std::runtime_error
{
public:
bad_value_cast(const char *w="") : std::runtime_error(w) {}
};
And here's value:
class value
{
private:
boost::shared_ptr<value_box> m_value_box;
public:
// a default value contains 'void'
value() : m_value_box( new value_box_impl<void>() ) {}
// embedd an object of type T.
template<class T>
value(const T &t) : m_value_box( new value_box_impl<T>(t) ) {}
// get the typeinfo of the embedded object
const typeinfo & type() const { return m_value_box->type(); }
// convenience type to simplify overloading on return values
template<class T> struct arg{};
template<class T>
T convert(arg<T>) const
{
if (type() != typeinfo::get<T>())
throw bad_value_cast();
// this is safe now
value_box_impl<T> *impl=
static_cast<value_box_impl<T>*>(m_value_box.get());
return impl->m_val;
}
void convert(arg<void>) const
{
if (type() != typeinfo::get<void>())
throw bad_value_cast();
}
};
The convenient casting syntax:
template<class T>
T value_cast(const value &v)
{
return v.convert(value::arg<T>());
}
And that's it. Here is how it looks like:
#include <string>
#include <map>
#include <iostream>
int main()
{
std::map<std::string,value> v;
v["zero"]=0;
v["pi"]=3.14159;
v["password"]=std::string("swordfish");
std::cout << value_cast<int>(v["zero"]) << std::endl;
std::cout << value_cast<double>(v["pi"]) << std::endl;
std::cout << value_cast<std::string>(v["password"]) << std::endl;
}
The nice thing about having you own implementation of any is, that you can very easily tailor it to the features you actually need, which is quite tedious with boost::any. For example, there are few requirements on the types that value can store: they need to be copy-constructible and have a public destructor. What if all types you use have an operator<<(ostream&,T) and you want a way to print your dictionaries? Just add a to_stream method to box and overload operator<< for value and you can write:
std::cout << v["zero"] << std::endl;
std::cout << v["pi"] << std::endl;
std::cout << v["password"] << std::endl;
Here's a pastebin with the above, should compile out of the box with g++/boost: http://pastebin.com/v0nJwVLW
EDIT: Added an optimization to avoid the allocation of box_impl< void > from the heap:
http://pastebin.com/pqA5JXhA
You can create a hash or map of string to boost::any. The string key can be extracted from any::type().

Implementing a no-op std::ostream

I'm looking at making a logging class which has members like Info, Error etc that can configurably output to console, file, or to nowhere.
For efficiency, I would like to avoid the overhead of formatting messages that are going to be thrown away (ie info messages when not running in a verbose mode). If I implement a custom std::streambuf that outputs to nowhere, I imagine that the std::ostream layer will still do all the formatting. Can anyone suggest a way to have a truly "null" std::ostream that avoids doing any work at all on the parameters passed to it with <<?
A swift google came up with this example which may be of use. I offer no guarantees, except that it compiles and runs :-)
#include <streambuf>
#include <ostream>
template <class cT, class traits = std::char_traits<cT> >
class basic_nullbuf: public std::basic_streambuf<cT, traits> {
typename traits::int_type overflow(typename traits::int_type c)
{
return traits::not_eof(c); // indicate success
}
};
template <class cT, class traits = std::char_traits<cT> >
class basic_onullstream: public std::basic_ostream<cT, traits> {
public:
basic_onullstream():
std::basic_ios<cT, traits>(&m_sbuf),
std::basic_ostream<cT, traits>(&m_sbuf)
{
init(&m_sbuf);
}
private:
basic_nullbuf<cT, traits> m_sbuf;
};
typedef basic_onullstream<char> onullstream;
typedef basic_onullstream<wchar_t> wonullstream;
int main() {
onullstream os;
os << 666;
}
all, thanks for sharing the code, I just do a test, then Neil's method will still do the string formating, for example:
#include <streambuf>
#include <ostream>
#include <iostream>
using namespace std;
template <class cT, class traits = std::char_traits<cT> >
class basic_nullbuf: public std::basic_streambuf<cT, traits> {
typename traits::int_type overflow(typename traits::int_type c)
{
return traits::not_eof(c); // indicate success
}
};
template <class cT, class traits = std::char_traits<cT> >
class basic_onullstream: public std::basic_ostream<cT, traits> {
public:
basic_onullstream():
std::basic_ios<cT, traits>(&m_sbuf),
std::basic_ostream<cT, traits>(&m_sbuf)
{
init(&m_sbuf);
}
private:
basic_nullbuf<cT, traits> m_sbuf;
};
typedef basic_onullstream<char> onullstream;
typedef basic_onullstream<wchar_t> wonullstream;
class MyClass
{
int a;
friend ostream& operator<< (ostream&, MyClass const&);
};
ostream& operator<<(ostream& out,MyClass const& b)
{
std::cout<<"call format function!!";
out << b.a;
return out;
}
int main() {
onullstream os;
MyClass obj;
os<<obj;
}
Running this program, you will find that "ostream& operator<<(ostream& out,MyClass const& b)" will be called. So, doing format on the obj will still be called. So, we still can't avoid the overhead of formatting messages.
To prevent the operator<<() invocations from doing formatting, you should know the streamtype at compile-time. This can be done either with macros or with templates.
My template solution follows.
class NullStream {
public:
void setFile() { /* no-op */ }
template<typename TPrintable>
NullStream& operator<<(TPrintable const&)
{ return *this; } /* no-op */
}
template<class TErrorStream> // add TInfoStream etc
class Logger {
public:
TErrorStream& errorStream() {
return m_errorStream;
}
private:
TErrorStream m_errorStream;
};
//usage
int main() {
Logger<std::ofstream> normal_logger; // does real output
normal_logger.errorStream().open("out.txt");
normal_logger.errorStream() << "My age is " << 19;
Logger<NullStream> null_logger; // does zero output with zero overhead
null_logger.errorStream().open("out.txt"); // no-op
null_logger.errorStream() << "My age is " << 19; // no-op
}
Since you have to do this at compile-time, it is of course quite inflexible.
For example, you cannot decide the logging level at runtime from a configuration file.
Probably you'll need more than just text formatting and message filtering. What about multithreading?
I would implement the filtering and multithreading synchronization as the responsibility of a separate class.
However, logging is a not-so-simple problem, and I would try to use existing logging solutions, instead of developing a new one.
Why not using existing logging solutions used by millions of users?
log4j, log4net, log4cxx.., to name just a few..

C++ template specialization question

I'm trying to implement a generic toString() function that would work on all types. All our internal classes derive from Abstract which includes a signature for toString(). In other words, all our internal classes have in some form, a toString method.
The problem is, the primitive types (int, char, double..) don't have a native toString function. But we do have a utility function that calls the lexical_cast to give back the string value of the primitive. We don't want a whole bunch of if statements depending So I'm trying to create a templated utility class that would do the job.
My first hack at this is the below:
template<class T>
class ObjectToString {
public:
string objectToString(T value) {
iil::stringUtils::StringSp ret(stringUtils::valueToString<T>(value));
return ret;
}
};
template<>
class ObjectToString <Abstract<T>*> {
public:
iil::stringUtils::StringSp objectToString(Abstract<T>* value) {
return iil::stringUtils::StringSp(new std::string("AAAA"));
}
};
The problem now is, since Abstract is a templated class, it needs the template value T. I have no idea how to set that. Could anyone advise?
How about simply providing a specialization for lexical_cast?
template<> string lexical_cast(Abstract* obj)
{
return obj->toString();
}
Isn't your problem much simpler? On all Abstract objects you know what to do, so all you need is to provide overloaded functions for built-in types:
string getAsString(Abstract *obj)
{
return obj->toString();
}
string getAsString(int x)
{
return intToStr(x);
}
string getAsString(double x)
{
return doubleToStr(x);
}
etc, where you implement intToStr() and doubleToStr() as appropriate.
This has been dealt with at length by Matthew Wilson in the form of shims, as described in this Dr Dobb's article, and the books Imperfect C++ and Extended STL. They underlie the technology that allow the FastFormat and Pantheios libraries to deal with argument types generically.
You just don't think in C++ way. C++ already has "toString" that is called operator<< to std::ostream. You need to implement it for your classes.
And if you want to support inheritence, do this:
#include <iostream>
#include <boost/lexical_cast.hpp>
#include <string>
class streamable {
public:
virtual void stream(std::ostream &) const = 0;
};
std::ostream &operator<<(std::ostream &out,streamable const &obj)
{
obj.stream(out);
return out;
}
// Now anything derived from streamable can be written to std::ostream
// For example:
class bar : public streamable {
int x;
int y;
public:
bar(int a,int b) : x(a),y(b){}
virtual void stream(std::ostream &out) const { out<<x<<":"<<y; }
};
int main()
{
bar b(1,3);
std::cout<< b << std::endl;
// and converted to string
std::string str=boost::lexical_cast<std::string>(b);
std::cout<< str <<std::endl;
}
This is C++ way, and as you can see you have boost::lexical_cast for free.
EDIT for your case:
template<typename T>
class Abstract {
public:
virtual void stream(std::ostream &) const = 0;
};
template<typename T>
std::ostream &operator<<(std::ostream &out,Abstract<T> const &obj)
{
obj.stream(out);
return out;
}
Now if you don't like boost::lexical_cast, implement string_cast as simple as
template<typename T>
std::string string_cast(T const &obj)
{
std::ostringstram ss;
ss<<obj;
return ss.str();
}