After reading this question Easy bitset I/O. I wanted to see if there was a simpler way of doing it.This is how I would define a way of outputting std::bitset<N> to the stream and reading it back in. It works perfectly with current containers.BitIO.h// Include guards deliberately not included for simplicity.#include <bitset>#include <iostream>template<int S>class BitIO{    public:    std::bitset<S>&     data;    BitIO(std::bitset<S>& data)        : data(data)    {}    friend std::ostream& operator<<(std::ostream& stream, BitIO const& value)    {        // Currently using just an integer.        //        // But we could easily take this a step further and use hex.        // and pad with 0 to get an exact width (that way we don't need a        // trailing space).        //        // Using a fixed width means we may potentially waste space but can        // be made to waste the least amount of space possible quite easily.        //        // Amount of wasted space would be (4 - (S % 4)) % 4        return stream << value.data.to_ullong() <<  ;    }    friend std::istream& operator>>(std::istream& stream, BitIO& value)    {        // As the current output uses a white space separated        // unsigned long long it is easy to read it back in using the        // normal `operator>>`        //        // Would be just as simple to convert this function to use        // a fixed width format to mirror the output.         unsigned long long tmp;        if (stream >> tmp)        {            value.data  = std::bitset<S>(tmp);        }        return stream;    }};main.cpp#include BitIO.h#include <vector>int main(){    std::vector<std::bitset<16> >    values { std::bitset<16>(1), std::bitset<16>(2), std::bitset<16>(255) };    std::copy(std::begin(values), std::end(values), std::ostream_iterator<BitIO<16>>(std::cout));    std::bitset<16>  data { 129 };    std::cout << BitIO<16>(data);}
Easy Bit IO. Very simple interface works up to N == 64
c++;io;bitset
The code is relatively short and well-written, so I didn't find many nits to pick.  With that said, here's my review:Include all needed filesSince std::ostream_iterator is declared in <iterator> that should be among the includes in main:#include <iterator>Use appropriate type for template parameterThe std::bitset template is defined as taking std::size_t rather than int, so it would make sense to define the BitIO template similarly:template<std::size_t S>class BitIO{    // ...};One can, of course, still abuse the interface by passing negative numbers but at least the user of the code is forewarned that they will be interpreted as std::size_t rather than as signed numbers.Consider implementing a move constructorAt the moment, this potential usage cannot compile:std::cout << BitIO<16>(std::bitset<16>{ 99 });It's easily fixed by adding this constructor:BitIO(std::bitset<S>&& data)    : data(data){}Maintain parallelism with existing practiceI was surprised to see spaces separating the outputs when none had been specified in the output ostream_iterator.  Although having the space is arguably useful, the choice of separator (if any) should be left up to the user of the template instead of being hardcoded in the operator << function.  I'd omit the trailing space to allow usage like this:std::copy(std::begin(values), std::end(values),         std::ostream_iterator<BitIO<16>>(std::cout,:));