views:

54

answers:

2

I am using a template function and I am passing and I may be sending instances of a variety of classes to a string stream. What can I do to make sure this continues to work?

Let me be more specific where do I define the behavior for this? Is there some member that should be on each class being sent to the string stream, should I in some enhance or extend the existing String stream (I was thinking building a class that inherits from sstream and overloads the << operator to handle all the possible classes)?

I had trouble even finding documentation on this, so even links to more resources would be helpful.

+5  A: 

It sounds to me like you want to make stream insertion operators. for a class you want to be able to output to a stream, define the free function:

std::ostream& operator<<(std::ostream& stream, const SomeClassType& x)
{
    stream << x.someData();

    return stream;
}

So if we have SomeClassType z;, and we do std::cout << z (or any other output stream, like an fstream or stringstream), the compiler will look for and find our function, and call it. That is, std::cout << z becomes operator<<(std::cout, z) and inside there you output what you need.

GMan
This is exactly what I needed
Sqeaky
+3  A: 

You just need to overload operator<< for those classes, e.g.

struct Point { int x, y; };

std::ostream& operator<<(std::ostream& os, const Point& p)
{
  return os << '(' << p.x << ", " << p.y << ')';
}

then you can use it in your function, which might be something like this:

template <class T>
std::string to_string(const T& x)
{
  std::stringstream ss;
  ss << x;
  return ss.str();
}

int main()
{
  Point p = {1, 2};
  std::string ps = to_string(p);
  std::cout << ps << std::endl; // (1, 2)
}
Peter Alexander