Search code examples
c++radixostreamstdiomanip

Why doesn't std::setbase(2) switch to binary output?


The cppreference page on std::setbase says:

Values of base other than 8, 10, or 16 reset basefield to zero, which corresponds to decimal output and prefix-dependent input.

How come?

Is there a particular reason why only these bases are supported? It seems trivial to support at least anything up to 16 (actually, up to 36: 0-9 and then a-z) without having to make any sort of difficult choices. Specifically, 2 is a popular base, I would think there should be interest in std::setbase(2) (and a corresponding std::binary).

I can obviously print my own bits but it would have been nice for my ostream to do it.


Solution

  • The only sure answer is "because the standard says so".

    That being said, the standard mostly formalized the pre-standard iostream implementations, many of which probably were designed just to reach feature parity with printf, which supports only decimal, octal and hexadecimal (through ad-hoc, not-really-general syntax).

    Also, as it is now it wouldn't be trivial to patch the iostream API to support "many" bases, given that the base setting ends up into a bitfield, not in a separate "current base" field.

    Now, the standard requires fmtflags to be of some "bitmask type" - which may even be a std::bitset, so you may find a way to shovel all those new "base" fields somehow - but is it really worth the effort (plus the risk of breaking the code that assumes that fmtflags is of an integral type) for a feature that almost nobody really cares about?

    So, to sum it up: bad initial design (like the rest of iostream, actually), nontrivial fix and no real user demand for such a feature.