Use a standard stream, and restore its settings afterwards I sometimes find myself changing stream settings (e.g. to output hexadecimal, or to change fill character), and needing to change those settings back afterwards, to avoid perturbing subsequent output.  This gets tedious, so I wrote a short class to act as a scope guard, restoring the settings when it is destructed.

Now we can "borrow" an input or output stream, and give it back in the condition we found it.

#include &lt;ios&gt;
#include &lt;iomanip&gt;

// Members are all public and mutable, so if we really don't want
// to restore any particular part of the state, we can override.
template&lt;class CharT, class Traits = typename std::char_traits&lt;CharT&gt;&gt;
struct save_stream_state
{
    std::basic_ios&lt;CharT,Traits&gt;&amp; stream;
    std::ios_base::fmtflags flags;
    std::locale locale;
    std::streamsize precision;
    std::streamsize width;
    CharT fill;

    save_stream_state(std::basic_ios&lt;CharT,Traits&gt;&amp; stream)
        : stream{stream},
          flags{stream.flags()},
          locale{stream.getloc()},
          precision{stream.precision()},
          width{stream.width()},
          fill{stream.fill()}
    {}

    // deleting copy construction also prevents move
    save_stream_state(const save_stream_state&amp;) = delete;
    void operator=(const save_stream_state&amp;) = delete;

    ~save_stream_state()
    {
        stream.flags(flags);
        stream.imbue(locale);
        stream.precision(precision);
        stream.width(width);
        stream.fill(fill);
    }
};


It's not strictly necessary to delete operator=, as the compiler won't generate one for a class with a non-static reference member, but I think it's better to be explicit there. 



Here's a simple test program that shows how it's used.  If you are using an old standards version, the template type deduction won't work - you'll need to specify the guard type in full (save_stream_state&lt;char&gt; and save_stream_state&lt;wchar_t&gt;).

#include &lt;iostream&gt;
int main()
{
    auto test = []() {
        std::cout &lt;&lt; std::setw(15) &lt;&lt; "Foo" &lt;&lt; ' '
        &lt;&lt; true &lt;&lt; ' ' &lt;&lt; 123456 &lt;&lt; '\n';
    };
    {
        test();
        const save_stream_state guard{std::cout};
        std::cout &lt;&lt; std::setfill('_') &lt;&lt; std::left &lt;&lt; std::uppercase
                  &lt;&lt; std::boolalpha &lt;&lt; std::hex &lt;&lt; std::showbase;
        test();
    } // stream restored here
    test();


    std::cout &lt;&lt; std::endl;


    // Now with wide-character stream:
    auto wtest = []() {
        std::wclog &lt;&lt; std::setw(15) &lt;&lt; L"Foo" &lt;&lt; L' '
        &lt;&lt; true &lt;&lt; L' ' &lt;&lt; 123456 &lt;&lt; L'\n';
    };
    {
        wtest();
        // AAA style initialization - and guard multiple streams
        auto const guard = { save_stream_state{std::wclog},
                             save_stream_state{std::wcin} };
        std::wclog &lt;&lt; std::setfill(L'_') &lt;&lt; std::left &lt;&lt; std::uppercase
                   &lt;&lt; std::boolalpha &lt;&lt; std::hex &lt;&lt; std::showbase;
        wtest();
    } // stream restored here
    wtest();
}
I agree with everything what @JiveDadson said in the comment. I believe there are some ways to improve current code.

 ## Syntax

To use the guard, people will need to introduce a scope. My desired syntax would be:

stream &lt;&lt; session &lt;&lt; settings &lt;&lt; data;


I'll present solution with the syntax above later.

My solution seem to solve only a subset of problems which original code does. Thus my point about syntax is not valid. Example can be multiple statement prints, in which case my solution would do unnecessary work.

Naming

Would it be better to use stream_state_guard? The code uses name guard in the tests. It is funny that tests reflect what was actually intended to be written. I found that it is the case in my code too.



Alternative solution

To achieve the syntax above, I've used some of the new features of C++17. My thoughts are a mess more than usual, so watch out for potential nitpicks.

First of all, session needs to be object of some empty type, just like nullptr is to nullptr_t or nullopt is to nullopt_t.

struct session_t {};
static inline constexpr session_t session;


inline is used to deal with linker.

Now, the class itself.

#include &lt;ios&gt;
#include &lt;iomanip&gt;
#include &lt;ostream&gt;

class session_stream
{
    std::ostream&amp; stream;
    std::ios_base::fmtflags flags;
    std::locale locale;
    std::streamsize precision;
    std::streamsize width;
    char fill;

    session_stream(std::ostream&amp; stream)
        : stream{stream},
          flags{stream.flags()},
          locale{stream.getloc()},
          precision{stream.precision()},
          width{stream.width()},
          fill{stream.fill()}
    {}

public:
    friend session_stream operator&lt;&lt;(std::ostream&amp; os, session_t);

    // deleting copy construction also prevents move
    session_stream(const session_stream&amp;) = delete;
    void operator=(const session_stream&amp;) = delete;

    template &lt;typename T&gt;
    std::ostream&amp; operator&lt;&lt;(T&amp;&amp; value)
    {
        stream &lt;&lt; std::forward&lt;T&gt;(value);
        return stream;
    }


    ~session_stream()
    {
        stream.flags(flags);
        stream.imbue(locale);
        stream.precision(precision);
        stream.width(width);
        stream.fill(fill);
    }
};


The code is just adjusted version from the question. Interesting things to note:


Constructor and copy semantics are private

Wrong usage is impossible through conventional means. People will need to be either too smart or cause undefined behavior.
Create an object only by using stream &lt;&lt; session

This might look fishy. Especially this line:

return session_stream{os};


Since C++17 this is guaranteed copy elision, thus it works even if copy constructor is unavailable. I don't think that guarantees impossibility of prolonging lifetime of session_stream, but it will guard against unintentional wrong usages.
Uses its own operator&lt;&lt; only on the first call

I wasn't sure if overload resolution and ADL won't intervene, so I decided to return ostream&amp; on operator&lt;&lt;. 


Rewritten tests:

#include &lt;iostream&gt;

int main()
{
    auto test = []() {
        std::cout &lt;&lt; std::setw(15) &lt;&lt; "Foo" &lt;&lt; ' '
                  &lt;&lt; true &lt;&lt; ' ' &lt;&lt; 123456 &lt;&lt; '\n';
    };
    {
        test();
        std::cout &lt;&lt; session &lt;&lt; std::setfill('_') &lt;&lt; std::left &lt;&lt; std::uppercase
                  &lt;&lt; std::boolalpha &lt;&lt; std::hex &lt;&lt; std::showbase &lt;&lt; std::setw(15) 
                  &lt;&lt; "Foo" &lt;&lt; ' ' &lt;&lt; true &lt;&lt; ' ' &lt;&lt; 123456 &lt;&lt; '\n';
        test();
    } // stream restored here
    test();
    std::cout &lt;&lt; std::endl;

}


Live on Wandbox.

And just for reference: sessions can be nested.