22

In Java, the standard is to define the method toString() to return a string representation of a class. Other than overloading operator<<, is there any such standard in C++? I know there are the std::to_string() methods to get a string representation of a number. Does the C++ standard speak of defining the method to_string() to serve similar purpose for a class, or is there a common practice followed by C++ programmers?

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
Ahmed A
  • 3,362
  • 7
  • 39
  • 57
  • Seems like the structures that need a `toString()` method would be outweighed by those who don't. Just my opinion. – Fantastic Mr Fox Oct 26 '15 at 23:42
  • What do you want the effect of this '*standard*' method to be? In C++ there is no standard way to define a 'conversion to string' (which more often than not is not sensibly possible) and hence no standard way to request such a conversion. – Walter Oct 26 '15 at 23:44
  • Nothing stops you from providing to_string() overloads for your own classes (or making some own function/method with another name) – deviantfan Oct 26 '15 at 23:44
  • You could also write type conversion operator for std::string, but that is not very common. – Karlis Olte Oct 26 '15 at 23:44
  • 2
    This question: "other than the standard way, is there a standard way?" – Lightness Races in Orbit Oct 26 '15 at 23:56
  • no and no. I use "std::string dump()" to provide state of object info in hex or tabular - typically for development. I use "std::string show()" for use in the program context for user support. – 2785528 Oct 26 '15 at 23:56
  • 8
    `operator std::string() const;` fight me – Ryan Haining Oct 27 '15 at 00:03
  • Java has the advantage of using the same string encoding on all platforms -- not so much in C++. You'd have to have both a `toString()` and a `toWString()`, and exactly what encoding those returned would vary from platform to platform. It would be a major pain to support. – MrEricSir Oct 27 '15 at 00:05
  • @LightnessRacesinOrbit there was a paper on this [discussed at Kona](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/), I did not see this mentioned in the trip reports. Let me check STLs. – Shafik Yaghmour Oct 27 '15 at 00:24
  • 1
    Thank you all for all your comment and insight. I am not looking for for what such a method would do (as in what would go into the returned string), but more so, a "common" method name that is agreed upon (hence the standard). If a class writer, decided to provide a method that returned a string representation of the class, at the least there is some sort of agreement on the method name (be it to_string, toString, etc). I figured to_string would be a good choice, since the std already provides such methods for primitive integer types. – Ahmed A Oct 27 '15 at 05:32
  • @AhmedA the operator would be the name of the member function `struct MyClass { operator std::string() const { return "MyClass"; } };` This would let you convert to string `MyClass mc; std::string s(mc);` – Ryan Haining Nov 05 '15 at 21:04
  • Based on your comment above, I edited the question to say, the question was about a standard 'name' for a method, rather than a standard way to implement the method. Also, could you please mark one of the answers as accepted, or post an answer yourself based on your comment above ? – Whirl Mind Nov 12 '15 at 16:18

4 Answers4

14

The standard way to do this kind of thing is to provide an insertion operator so that an object can be inserted into a stream -- which may be any kind of stream, such as a stringstream.

If you wish, you can also provide a method that converts to a string (useful for your insertion operator), and, if you find the conversion acceptable, you can provide a 'to string' operator.

Here's my standard 'point' class example:

template <typename T>
struct point
{
  T x;
  T y;
  point(): x(), y() { }
  point( T x, T y ): x(x), y(y) { }
};

template <typename T>
std::ostream& operator << ( std::ostream& outs, const point <T> & p )
{
  return outs << "(" << p.x << "," << p.y << ")";
}

I also tend to keep a handy function around to convert things to strings:

template <typename T>
std::string to_string( const T& value )
{
  std::ostringstream ss;
  ss << value;
  return ss.str();
}

Now I can use it easily:

int main()
{
  point p (2,-7);

  std::cout << "I have a point at " << p << ".\n";

  my_fn_which_takes_a_string( to_string(p) );

You'll find that the Boost Lexical Cast Library is also designed for this kind of thing.

Hope this helps.

Dúthomhas
  • 8,200
  • 2
  • 17
  • 39
4

The C++ standard does not prescribe a way to do this but it looks like there is a proposal which may introduce such an option Generic to_string/to_wstring functions which says in the motivation section which also highlights the current common practices being taken(which I demonstrate below):

For a long time C++ programmers have been looking for an easy way to convert an object into its string representation. A typical answer to this problem was to create a local ostringstream, insert the object into the stream, and then obtain the resulting string with the str member function. This solution is simple, safe, flexible and extensible, though definitely too verbose for something that rather ought to be a single function call. C++11 provided (a partial) solution in the form of a set of overloaded to_string/to_wstring functions. Unfortunately, these are limited only to the built-in numeric types. Non-standard solutions exist too – most notably boost::lexical_cast, which offers two-way conversion of objects and strings, but lacks any formatting control.

This paper proposes a solution that:

  • generalizes the existing to_string/to_wstring functions for any type that provides a stream output operator and for any basic_string specialisation,
  • remains consistent and mostly compatible with these functions,
  • provides extra formatting and concatenation capabilities,
  • is conceptually simple by building upon the familiar ostringstream solution.

There are two trip reports STL's and Herb Sutter's and I don't see this paper mentioned in either. So hopefully this will be covered in the post-Kona mailing when it comes out.

The first method they mentioned in the proposal would look something like the example in this answer:

class A {
public:
  int i;
};

std::ostream& operator<<(std::ostream &strm, const A &a) {
  return strm << "A(" << a.i << ")";
}

combined with the something similar to the example from here:

template <typename T>
std::string to_string(const T& value) {
  std::ostringstream os;
  os << value;
  return os.str();
}

We can find a boost::lexical_cast example in the question Enabling Classes for Use with boost::lexical_cast.

Community
  • 1
  • 1
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
3

Looks like there is no standard way. As I understand C++ standard does not permit overloading of std::to_string function.

I ended up using one of these two solutions:

Solution #1

Instead of toString() method you can use:

operator std::string() const {
    return "Object string.";
}

And to support streams you can add something like this:

friend std::ostream & operator <<(std::ostream &out, const YourClass &obj) {
    return out << static_cast<std::string>(obj);
}

I hope that the << operator will just inline the conversion from the first operator.

Solution #2

Or you can go other way if you think often in the stream-style:

friend std::ostream & operator <<(std::ostream &out, const YourClass &obj) {
    out << "Object ";
    out << "string.";
    return out;
}

And use it inside conversion operator:

operator std::string() const {
    std::ostringstream out;
    out << *this;
    return out.str();
}

Either way this get you covered for most of the cases.

Konard
  • 2,298
  • 28
  • 21
1

Does the C++ standard speak of defining the method to_string() to serve similar purpose for a class,

No.

or is there a common practice followed by C++ programmers.

No. However, I suspect every project has similar functionality. The name and return type most likely depend on the coding guidelines of a project.

At my work, we use

virtual QString toString() const = 0;

in one of our base classes.

You can start using something similar for your project.

virtual std::string toString() const = 0;

in your base class(es).

R Sahu
  • 204,454
  • 14
  • 159
  • 270