2270. Inconsistent to_string overloads

Section: 27.4.5 [string.conversions] Status: NAD Submitter: Raf Schietekat Opened: 2013-07-02 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [string.conversions].

View all issues with NAD status.

Discussion:

For internal consistency, to_string() should either list all relevant types (including bool, char, etc.), or only those that are the destination types of integral or floating-point promotion (float not being among them).

A defensible reason for having (or rather keeping) the float overloads anyway could be to exactly mirror the adjacent sets of stoX() function overloads (even without round-trip fidelity for floating-point numbers).

Unfortunately, that reveals a bigger issue than redundant overloads: the glaring and indefensible omission of an overloaded function stoui(). Adding that is not as trivial as removing redundant overloads, of course, because it requires everybody to take action. Still, it is the preferable remedy for the present situation.

As far as I can tell from easily accessible information, C++ has already created the precedent with stoi(), which is not the equivalent of a pair of functions strtoi()/wcstoi() in C, but it would be if such functions existed. The function atoi() may look similar, but it does not qualify because it is as different from a hypothetical strtoi() as atol() currently is from strtol(), with the latter two both Standard C. It is only logical to act on this one-sided precedent by completing the set. Whether or not Standard C leads the way (or follows suit) is immaterial, but an invitation could be extended.

[2013-09 Chicago]

These overloads were very carefully and experimentally determined to be the minimal set, when all (known) promotion and conversion scenarios were considered. Removing superfluous-looking overloads is likely to result in ambiguities.

Proposed resolution:

This wording is relative to N3691.

  1. Modify 27.4 [string.classes], header <string> synopsis, as indicated:

    #include <initializer_list>
    
    namespace std {
      […]
      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);
      […]
    
      […]
      wstring to_wstring(int val);
      wstring to_wstring(unsigned val);
      wstring to_wstring(long val);
      wstring to_wstring(unsigned long val);
      wstring to_wstring(long long val);
      wstring to_wstring(unsigned long long val);
      wstring to_wstring(float val);
      wstring to_wstring(double val);
      wstring to_wstring(long double val);
      […]
    }
    
  2. Modify 27.4.5 [string.conversions] p7+14 as indicated:

    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);
    

    -7- Returns: Each function returns a string object holding the character representation of the value of its argument that would be generated by calling sprintf(buf, fmt, val) with a format specifier of "%d", "%u", "%ld", "%lu", "%lld", "%llu", "%f", "%f", or "%Lf", respectively, where buf designates an internal character buffer of sufficient size.

    […]

    wstring to_wstring(int val);
    wstring to_wstring(unsigned val);
    wstring to_wstring(long val);
    wstring to_wstring(unsigned long val);
    wstring to_wstring(long long val);
    wstring to_wstring(unsigned long long val);
    wstring to_wstring(float val);
    wstring to_wstring(double val);
    wstring to_wstring(long double val);
    

    -14- Returns: Each function returns a wstring object holding the character representation of the value of its argument that would be generated by calling swprintf(buf, buffsz, fmt, val) with a format specifier of L"%d", L"%u", L"%ld", L"%lu", L"%lld", L"%llu", L"%f", L"%f", or L"%Lf", respectively, where buf designates an internal character buffer of sufficient size buffsz.