Title
basic_ostream uses nonexistent num_put member functions
Status
cd1
Section
[ostream.inserters.arithmetic]
Submitter
Matt Austern

Created on 1998-11-20.00:00:00 last changed 172 months ago

Messages

Date: 2010-10-21.18:28:33

Rationale:

The original proposed resolution was to cast int and short to long, unsigned int and unsigned short to unsigned long, and float to double, thus ensuring that we don't try to use nonexistent num_put<> member functions. The current proposed resolution is more complicated, but gives more expected results for hex and octal output of signed short and signed int. (On a system with 16-bit short, for example, printing short(-1) in hex format should yield 0xffff.)

Date: 2010-10-21.18:28:33

[ post-Toronto: This differs from the previous proposed resolution; PJP provided the new wording. The differences are in signed short and int output. ]

Date: 2010-10-21.18:28:33

Proposed resolution:

Replace 27.6.2.5.2, paragraph 1 with the following:

The classes num_get<> and num_put<> handle locale-dependent numeric formatting and parsing. These inserter functions use the imbued locale value to perform numeric formatting. When val is of type bool, long, unsigned long, double, long double, or const void*, the formatting conversion occurs as if it performed the following code fragment:

bool failed = use_facet<
   num_put<charT,ostreambuf_iterator<charT,traits> >
   >(getloc()).put(*this, *this, fill(), val). failed();

When val is of type short the formatting conversion occurs as if it performed the following code fragment:

ios_base::fmtflags baseflags = ios_base::flags() & ios_base::basefield;
bool failed = use_facet<
   num_put<charT,ostreambuf_iterator<charT,traits> >
   >(getloc()).put(*this, *this, fill(),
      baseflags == ios_base::oct || baseflags == ios_base::hex
         ? static_cast<long>(static_cast<unsigned short>(val))
         : static_cast<long>(val)). failed();

When val is of type int the formatting conversion occurs as if it performed the following code fragment:

ios_base::fmtflags baseflags = ios_base::flags() & ios_base::basefield;
bool failed = use_facet<
   num_put<charT,ostreambuf_iterator<charT,traits> >
   >(getloc()).put(*this, *this, fill(),
      baseflags == ios_base::oct || baseflags == ios_base::hex
         ? static_cast<long>(static_cast<unsigned int>(val))
         : static_cast<long>(val)). failed();

When val is of type unsigned short or unsigned int the formatting conversion occurs as if it performed the following code fragment:

bool failed = use_facet<
   num_put<charT,ostreambuf_iterator<charT,traits> >
   >(getloc()).put(*this, *this, fill(), static_cast<unsigned long>(val)).
failed();

When val is of type float the formatting conversion occurs as if it performed the following code fragment:

bool failed = use_facet<
   num_put<charT,ostreambuf_iterator<charT,traits> >
   >(getloc()).put(*this, *this, fill(), static_cast<double>(val)).
failed();
Date: 1998-11-20.00:00:00

The effects clause for numeric inserters says that insertion of a value x, whose type is either bool, short, unsigned short, int, unsigned int, long, unsigned long, float, double, long double, or const void*, is delegated to num_put, and that insertion is performed as if through the following code fragment:

bool failed = use_facet<
   num_put<charT,ostreambuf_iterator<charT,traits> > 
   >(getloc()).put(*this, *this, fill(), val). failed();

This doesn't work, because num_put<>::put is only overloaded for the types bool, long, unsigned long, double, long double, and const void*. That is, the code fragment in the standard is incorrect (it is diagnosed as ambiguous at compile time) for the types short, unsigned short, int, unsigned int, and float.

We must either add new member functions to num_put, or else change the description in ostream so that it only calls functions that are actually there. I prefer the latter.

History
Date User Action Args
2010-10-21 18:28:33adminsetmessages: + msg997
2010-10-21 18:28:33adminsetmessages: + msg996
2010-10-21 18:28:33adminsetmessages: + msg995
1998-11-20 00:00:00admincreate