I'm experimenting with the iostreams / locale numeric facet and I've hit something quite curious:
The "canonical example" of using the std::num_put facet to directly format a number goes like this:
std::string f(double value) {
using namespace std;
stringstream ss;
num_put<char> const& npf = use_facet<num_put<char> >(ss.getloc());
npf.put(/*out=*/ss, /*format=*/ss, /*fill=*/' ', value);
return ss.str();
}
The first parameter to put
is the thing where the output is written to.
We can also have code like this and it works:
std::string g(double value) {
using namespace std;
stringstream ss;
typedef char* CharBufOutIt;
num_put<char, CharBufOutIt> const& npf = use_facet<num_put<char, CharBufOutIt> >(ss.getloc());
char big_enough_buf[100];
npf.put(/*out=*/big_enough_buf, /*format=*/ss, /*fill=*/' ', value);
return big_enough_buf;
}
The second parameter to put()
is a stream object that determines the specific formatting to be applied. The second parameter is not modified at all. (Not in my implementation, and not according to what the docs describe this parameter to be for.)
However, the signature of put
looks like this:
iter_type put( iter_type out, std::ios_base& str, char_type fill, long double v ) const;
That is, it is taking the ios_base object by non-const reference, even though it wouild appear it should really take it by const reference.
Am I missing something? Is this just a (historical?) peculiarity in the C++ iostreams spec? Has this ever been discussed by the C++ std committee?
From the Standard (22.4.2.2.2) the implementation of
put
is at one point as such:Also,
str.width(0)
callswidth
declared withoutconst
(see this link):