The easy approach to restore the original format is to keep a stream without any modifications around and just use copyfmt()
, e.g.:
int main() {
std::ostream restore(0);
restore.copyfmt(std::cout);
std::cout.precision(8);
std::cout.copyfmt(restore);
}
This approach will restore all the different formats, including the values stored with pword()
and iword()
. If you want to package this functionality as a set_default
manipulator (you can't put it into namespace std
as only implementers are allowed to put names in there), you'd use something like this:
template <typename cT, typename Traits>
std::basic_ostream<cT, Traits>& set_default(std::basic_ostream<cT, Traits>& out) {
static std::basic_ostream<cT, Traits> dfault(0);
out.copyfmt(dfault);
return out;
}
It would be used like any of the other manipulators, e.g.:
std::cout << set_default;
You can just have one stream from which to restore the original values. Alternatively, you can keep the format of std::cout
intact and rather create a separate stream using the same buffer but different formats, e.g.
std::ostream out(std::cout.rdbuf());
out.precision(8);
out << value;
This stream will write to the same stream as std::cout
but use different formatting flags. You can even mix them as the streams don't store any characters directly: this is the job of the shared stream buffer:
std::cout << "value=";
out << value;
std::cout << '\n';
To answer your question about the behavior of, e.g., defaultfloat
: these are just manipulator functions. If you want to use them without C++11 you can just define a corresponding function, e.g.:
template <typename cT, typename Traits>
std::basic_ostream<cT, Traits>& defaultfloat(std::basic_ostream<cT, Traits>& out) {
out.unsetf(std::ios_base::floatfield);
return out;
}