I recently had a problem creating a stringstream
due to the fact that I incorrectly assumed std::setw()
would affect the stringstream for every ins
The reason that width
does not appear to be 'sticky' is that certain operations are guaranteed to call .width(0)
on an output stream. Those are:
21.3.7.9 [lib.string.io]:
template
basic_ostream&
operator<<(basic_ostream& os,
const basic_string& str);
22.2.2.2.2 [lib.facet.num.put.virtuals]: All do_put
overloads for the num_put
template. These are used by overloads of operator<<
taking a basic_ostream
and a built in numeric type.
22.2.6.2.2 [lib.locale.money.put.virtuals]: All do_put
overloads for the money_put
template.
27.6.2.5.4 [lib.ostream.inserters.character]: Overloads of operator<<
taking a basic_ostream
and one of the char type of the basic_ostream instantiation or char
, signed char
or unsigned char
or pointers to arrays of these char types.
To be honest I'm not sure of the rationale for this, but no other states of an ostream
should be reset by formatted output functions. Of course, things like badbit
and failbit
may be set if there is a failure in the output operation, but that should be expected.
The only reason that I can think of for resetting the width is that it might be surprising if, when trying to output some delimited fields, your delimiters were padded.
E.g.
std::cout << std::setw(6) << 4.5 << '|' << 3.6 << '\n';
" 4.5 | 3.6 \n"
To 'correct' this would take:
std::cout << std::setw(6) << 4.5 << std::setw(0) << '|' << std::setw(6) << 3.6 << std::setw(0) << '\n';
whereas with a resetting width, the desired output can be generated with the shorter:
std::cout << std::setw(6) << 4.5 << '|' << std::setw(6) << 3.6 << '\n';