Why is there only `to_string ()` for number types?

I just found out that C ++ has std::to_string() defined in <string> . Now I wonder why to_string() only works with number types. Is there any special reason why there is no more general

 template <typename T> std::string to_string(const T& t); 

?

It can be implemented as follows:

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

I suspect that such a common to_string does not exist, because it is easy to write on your own, but the same argument applies to to_string() , which accepts int , double , etc.

+5
source share
2 answers

Due to std::to_string() requirements.

As standard states:

string to_string(int val);

string to_string(unsigned val);

string to_string(long val);

string to_string(unsigned long val);

string to_string(long long val);

string to_string(unsigned long long val);

string to_string(float val);

string to_string(double val);

string to_string(long double val);

Returns: each function returns a string object containing a character representing the value of its argument, which will be generated by calling sprintf (buf, fmt, val) with the format specifier "% d", "% u", "% ld", "% lu", "% lld", "% llu", "% f", "% f" or "% Lf", respectively, where buf denotes an internal character buffer of sufficient size.

Writing a boilerplate function that can specify the qualifier that should be used for std::sprintf makes things unnecessarily complicated.

+4
source

I just want to add to the answer of Gill Bates what I found in this sentence (thanks to @DAle for the link).

Proposal to add a common to_string method. They, of course, talk about the true generic method, but the principle will be the same as my naive almost general one: under the hood, a stream is used to get a string from any object that can be transferred.

Since the sentence appeared after C ++ 11, adding such a method would affect the existing to_string and in the section “Impact on the standard” they write:

[...] Old and new functions can coexist, relying on overload to prefer a non-template (existing) version in the case of the corresponding type of argument. However, a compatibility problem may arise in the case of some different, but implicitly convertible argument types:

 to_string(0); // before: calls to_string(int), now: calls to_string(int) to_string(false); // before: calls to_string(int), now: calls to_string<bool>(bool&&) to_string('0'); // before: calls to_string(int), now: calls to_string<char>(char&&) 

While the effect is identical in the first two cases (the result is always “0”), in the latter case the result will change from “48”, (subject to ASCII coding) to “0”. There are several ways to deal with problematic specialization cases like this:

And then they list some parameters (including ignoring the problem) of which imho will not really satisfy. IMHO it's a pity that to_string , because it turns into a standard in the first place. Gill Bates answer, on the other hand, provides a good reason why it was not created from the very beginning (assuming it generates a string as if sprintf used, this is not trivial at all, but it may be impossible).

+3
source

Source: https://habr.com/ru/post/1266711/


All Articles