为什么没有<< overload for printing std::byte?

问题描述 投票:0回答:2

以下代码无法在 C++20 中编译

#include <iostream>
#include <cstddef>

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

当C++17中添加

std::byte
时,为什么没有相应的
operator<<
重载来打印它?我也许可以理解不打印容器的选择,但为什么不呢
std::byte
?它尝试充当原始类型,我们甚至对
std::string
、最近的
std::string_view
也许是最相关的
std::complex
std::bitset
本身进行了重载。

还有

std::hex
和类似的修饰符,因此默认打印 0-255 应该不是问题。

这只是疏忽吗?

operator>>
呢,
std::bitset
都有,而且一点也不小。

编辑:发现甚至可以打印

std::bitset

c++ c++20 stdout iostream std-byte
2个回答
22
投票

来自std::byte

(P0298R3)
论文:(强调我的)

设计决策

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

这里的关键动机是使字节成为一种独特的类型——通过利用类型系统来提高程序安全性。这就导致了

std::byte
的设计不是整数类型,也不是字符类型。它是一个独特的 用于访问最终构成对象存储的位的类型。

(强调我的)

因此,不需要隐式转换/解释为

char
或任何整数类型,因此不能使用
std::cout
打印,除非显式转换为所需类型。

此外,请参阅如何在需要旧式 unsigned char 的地方使用新的 std::byte 类型?.


8
投票

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

强调:

std::byte
并不“试图成为一个原始人”,它代表了一些甚至更少的东西 - 原始数据。

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

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

例如,我的用例是通过 I2C(或 RS485)接收原始字节并将其解析为帧,然后将其放入

struct
中。为什么我想在实际数据上序列化原始字节?我几乎可以立即访问数据?

总结一下这个有点啰嗦的答案,为

std::byte
提供运算符重载以与
iostream
一起使用违背了这种类型的意图。

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

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.