为什么打印 `std::byte` 没有过载?

以下代码不能在 C++20 中编译

#include <iostream>
#include <cstddef>

int main(){ 
    std::byte b {65};
    std::cout<<"byte: "<<b<<'\n';// Missing overload
}

std::byteC++17什么时候加入的,为什么没有对应的operator<<重载打印呢?我也许可以理解不打印容器的选择,但为什么不std::byte呢?它试图充当原始类型,我们甚至有 的重载std::string,最近的std::string_view也许是最相关的 std::complex并且std::bitset它本身可以被打印。

还有std::hex类似的修饰符,所以默认打印 0-255 应该不是问题。

这只是疏忽吗?怎么样operator>>std::bitset有它,它根本不是微不足道的。

编辑:发现甚至std::bitset可以打印。

回答

来自(P0298R3)上std::byte的论文:(强调我的)

std::byte 不是整数也不是字符

这里主要动机是使字节成为一种独特的类型——通过利用类型系统来提高程序安全性。这导致了设计,std::byte不是整数类型,也不是一个字符类型。它是一种用于访问最终构成对象存储的位的独特类型。

因此,不需要隐式转换/解释为 achar或任何整数类型,因此std::cout除非显式转换为所需类型,否则不能使用打印。

此外,这个问题可能会有所帮助。

  • @Quimby 你写了 `std::cout&lt;&lt;std::to_integer&lt;int&gt;(b);` 但我认为(标准背后的原理)的重点是 `std::cout&lt;&lt;std::to_char( b);` 的可能性相同。似乎这个想法是 `std::byte` 可以是一个数字、一个字符、一个数字的一​​部分、一个字符或其他一些类型或数据。
  • 不提供该功能并不是“避免为用户做出选择”,它只是乏味,不那么用户友好,并且违背了 `std::byte` 提高代码可读性和安全性的目的。无论如何,这可能是我得到的最佳答案,如果没有其他问题出现,我会再等一会儿并接受它。
  • @Quimby 没有人将 `std::bitset` 误认为是文本,也不会将其误认为是可以进行算术运算的东西。*不*提供操作可以提高类型安全性

std::byte用于访问原始数据。允许我uint8_t用实际上说“这是原始且未解析的”的东西代替散布在代码库中的该死的东西,而不是可能被误解为 C 字符串的东西。

强调:std::byte不是“试图成为原始人”,它代表的东西甚至更少- 原始数据。

像这样实现它主要是 C++ 和编译器实现的一个怪癖(“原始”类型的布局规则比结构或类简单得多)。

这种事情主要出现在低级代码中,老实说,不应该使用打印。有时是不可能的

例如,我的用例是通过 I2C(或 RS485)接收原始字节并将它们解析为帧,然后将其放入struct. 为什么我要在实际数据上序列化原始字节?我几乎可以立即访问数据?

总结一下这个有点啰嗦的答案,提供操作符重载std::byte来处理与iostream这种类型的意图背道而驰。

而尽可能在代码中表达意图是现代编程的重要原则之一。


以上是为什么打印 `std::byte` 没有过载?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>