为什么 std::setbase(2) 不切换到二进制输出?

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

The cppreference page on std::setbase 说:

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

怎么会?

仅支持这些碱基是否有特殊原因?支持至少 16 个(实际上,最多 36 个:0-9,然后是 a-z)而不必做出任何困难的选择似乎是微不足道的。具体来说,2是一个受欢迎的基础,我认为应该对std::setbase(2)(以及相应的std::binary)感兴趣。

我显然可以打印自己的位,但如果我的 ostream 能做到这一点就好了。

唯一确定的答案是 "because the standard says so"。

话虽这么说,该标准主要是对准标准 iostream 实现进行了形式化,其中许多可能只是为了达到与 printf 的功能对等而设计的,printf 仅支持十进制、八进制和十六进制(通过 ad-特殊的,不是真正通用的语法)。

另外,就像现在一样,修补 iostream API 以支持 "many" 基础并不是一件容易的事,因为基础设置最终进入位域,而不是单独的"current base" 字段。

现在,标准要求 fmtflags 属于某些 "bitmask type" - 甚至可能是 std::bitset,因此您可能会找到一种方法来铲除所有这些新的 [=28] =] 字段 - 但它真的值得付出努力(加上破坏假定 fmtflags 是整数类型的代码的风险)以获得几乎没有人真正关心的功能吗?

因此,总结一下:糟糕的初始设计(实际上与 iostream 的其余部分一样)、重要的修复以及没有真正的用户需求这样的功能。

据我所知,没有建议向 iostream 添加对二进制(base 2)格式的支持(另请参阅 ). However, it is supported in C++20 std::format:

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

std::format 没有广泛使用,但您可以使用 the {fmt} librarystd::format 是基于,同时:

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

免责声明:我是 {fmt} 和 C++20 的作者 std::format