I have a class similar to boost :: any, since this is a template container class. I would like to have a method for writing the contained value to a string. However, if the contained type does not provide a stream insert operator, I would like my method to return some trigger by default rather than compile it. Below, as close as I came, and should clearly indicate what I'm trying to do:
namespace W { namespace hide { template <typename T> std::ostream& operator<<(std::ostream& out, const T& t) { return std::operator<<(out, typeid(T).name()); } } template <typename T> struct C { T t_; std::string ToString() const { using namespace hide; std::ostringstream oss; oss << t_; return oss.str(); } }; }
This works very well, with some caveats. For example, if I want to actually provide an overloaded insert operator for a class, then this operator must either be in the same namespace as the class, or it must be in the W namespace so that it is read.
It also has problems with any type that the non-member std :: operator <<char and std :: string already has. If T is one of these types, then the line oss << t_ above becomes ambiguous. This can be circumvented by adding overloads for these types inside the W namespace, for example:
std::ostream& operator << (std::ostream& out, const std::string& s) { return std::operator <<(out, s); }
My question is: has anyone found a better method than this? Why should I add my own overloads for things like std :: string? Is it supported according to the standard, or am I using non-standard behavior? (I am testing g ++ 4.3.3)
c ++ iostream overloading templates
JimSteele1222
source share