10

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.

einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • 2
    the nice way to print binary is http://en.cppreference.com/w/cpp/utility/bitset/operator_ltltgtgt2 – Cubbi Apr 19 '16 at 02:40
  • @Cubbi: That is nice, but it requires the code printing to the stream to be aware of the need to print in binary. I want the _stream_ to convert to binary. – einpoklum Apr 19 '16 at 09:04

2 Answers2

7

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.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
5

To the best of my knowledge there was no proposal to add support for binary (base 2) formatting to iostreams (see also Has there been a proposal to add std::bin to the c++ standard?). However, it is supported in C++20 std::format:

std::string s = std::format("{:b}", 42);

std::format is not widely available but you can use the {fmt} library, std::format is based on, in the meantime:

std::string s = fmt::format("{:b}", 42);

Disclaimer: I'm the author of {fmt} and C++20 std::format.

vitaut
  • 49,672
  • 25
  • 199
  • 336