I got tired of the boilerplate and tedium restoring formatting context, so I made an RAII stasher that relies on the destroy-at-end-of-full-statement temporary semantics. With C++17 I can get it down to a single type, no helpers:
#include <iostream>
template< template<typename, class> class streamtmp, typename _CharT, class _Traits >
struct fmtstash {
typedef streamtmp<_CharT,_Traits> streamtype;
streamtype &from;
std::ios_base::fmtflags flags;
std::streamsize width;
std::streamsize precision;
fmtstash(streamtype &str) :
from(str), flags(str.flags()), width(str.width()), precision(str.precision()) { }
~fmtstash() { from.flags(flags), from.width(width), from.precision(precision); }
template<typename _T> streamtype &operator<<(const _T &rhs) { return from.operator<<(rhs); }
template<typename _T> streamtype &operator>>(const _T &rhs) { return from.operator>>(rhs); }
};
int main(int c, char **v)
{
using namespace std;
fmtstash(cout) << hex << 51901 <<'\n';
cout << 51901 <<'\n';
return 0;
}
which produces about the easiest-to-write-and-read formatting I can manage.
Am I missing any bets here? Shorter or more robust is what I'm after.