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

10

std::setbase的cppreference页面如下所述:

除了8、10或16进制以外的基数值会将 basefield 重置为零,这对应于十进制输出和前缀相关的输入。

为什么呢?

只支持这些基数有特殊原因吗?似乎至少能够支持到16(实际上是36:0-9,然后是a-z)而不需要做任何困难的选择。具体而言,2是一种常见的基数,我认为应该有人对std::setbase(2)(以及相应的std::binary)感兴趣。

我当然可以自己打印二进制位,但我的ostream来做这件事会更好。


2
打印二进制的好方法是使用http://en.cppreference.com/w/cpp/utility/bitset/operator_ltltgtgt2。 - Cubbi
@Cubbi:那很好,但它要求将代码打印到流中的人知道需要以二进制形式打印。我希望这个“流”自动转换为二进制。 - einpoklum
2个回答

7
唯一确定的答案是“因为标准规定如此”。
话虽如此,该标准大多数是将预标准iostream实现形式化,其中许多可能仅设计为达到与printf的功能对等,后者仅支持十进制,八进制和十六进制(通过特定的,不真正通用的语法)。
此外,现在要修补iostream API以支持“许多”基本类型并不容易,因为基本设置最终会进入位字段,而不是单独的“当前基础”字段。
现在,标准要求fmtflags必须是某种“位掩码类型” - 这甚至可以是std :: bitset,因此您可以找到一种方法来传输所有这些新的“基本”字段 - 但是为了一个几乎没有人真正关心的功能而付出的努力(以及破坏假设fmtflags是整数类型的代码的风险)是否真的值得?
因此,总结一下:初始设计不好(实际上就像iostream的其余部分一样),非平凡修复以及几乎没有真正用户需要此功能。

5
据我所知,目前没有任何提案将二进制(基数2)格式添加到iostreams中(参见有没有提议将std::bin添加到c++标准中?)。但是,在C++20中,std::format已经支持该功能。
std::string s = std::format("{:b}", 42);

std::format并不是很常用,但在此期间你可以使用基于std::format{fmt}库:

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接