标签: std-byte

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

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

#include <iostream>
#include <cstddef>

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

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

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

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

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

c++ stdout string-view c++20 std-byte

17
推荐指数
2
解决办法
1034
查看次数

C++17 中 std::byte 只能按位运算?

CPP 参考文献中指出:

std::byte是一种独特的类型,它实现了 C++ 语言定义中指定的字节概念。

与 char 和 unsigned char 一样,它可用于访问其他对象(对象表示)占用的原始内存,但与这些类型不同的是,它不是字符类型,也不是算术类型。字节只是位的集合,并且只为其定义了按位运算符

但这不是真的:因为它是枚举类型,所以比较操作(<, <=, >, >=, ==, !=)也是可能的。

这是故意的吗,例如std::byte也用作 等的密钥std::map

c++ byte language-lawyer std-byte

15
推荐指数
1
解决办法
907
查看次数

整数提升带来的 std::byte 开销

考虑unsigned char v进行一系列按位运算并将结果存储回 的情况v。在底层,它被整数提升一次,经历一系列操作,结果被截断并存储回v

然而std::byte v,对于每个操作,操作数首先被提升为整数,进行操作,并且(中间)结果被截断并存储回某个std::byte。这将是许多来回的提升和截断。这都是概念性的,但它会在实践中造成真正的开销吗?

人工例子

// `mask` and `lshf` are of type `unsigned`
unsigned char v = ...;
v = (v & mask) << lshf; // one promotion at `&` and one truncation at `=`
Run Code Online (Sandbox Code Playgroud)
// `mask` and `lshf` are of type `std::byte` and `unsigned`
std::byte v = ...;
v = (v & mask) << lshf;

// It would be like
// byte(unsigned(byte(unsigned(v) & unsigned(mask))) << …
Run Code Online (Sandbox Code Playgroud)

c++ type-conversion integer-promotion c++17 std-byte

6
推荐指数
0
解决办法
122
查看次数

C++17 std::byte 使用 GCC 中的标准算法生成优化程度较低的代码

我真的很喜欢std::byte作为一种独特的类型,它实现了 C++ 语言定义中指定的字节概念。我不喜欢的是,现代 C++ 编译器将使用标准算法生成优化程度较低的代码。

在这里,我正在使用一个检查标头中前 4 个字节的函数,您可以在Godbolt上关注我的代码片段

bool func_bytes(const std::array<std::byte, 1024>& buf) {
    constexpr std::array<std::byte, 4> header {
        std::byte{0xDE}, std::byte{0xAD}, std::byte{0xBE}, std::byte{0xAF}
    };
    return std::equal(header.begin(), header.end(), buf.begin());
}
Run Code Online (Sandbox Code Playgroud)

这将在 x86-64 gcc trunk 上生成以下程序集

func_bytes(std::array<std::byte, 1024ul> const&):
        cmp     BYTE PTR [rdi], -34
        jne     .L5
        cmp     BYTE PTR [rdi+1], -83
        jne     .L5
        cmp     BYTE PTR [rdi+2], -66
        jne     .L5
        cmp     BYTE PTR [rdi+3], -81
        sete    al
        ret
.L5:
        xor     eax, eax
        ret
Run Code Online (Sandbox Code Playgroud)

如果我将 替换std::byteunsigned char …

c++ gcc x86-64 memcmp std-byte

5
推荐指数
1
解决办法
270
查看次数

是否可以将 std::byte 向后移植到 C++14

std::byte在 C++17 中定义为:

enum class byte : unsigned char {};
Run Code Online (Sandbox Code Playgroud)

我目前坚持使用 C++14,我想知道如果我在 C++14 中添加相同的定义(在某些非 std 命名空间中,以及运算符重载等),这个新类型会得到相同的结果吗?将“free-pass”别名化为unsigned char或由于违反严格的别名规则而将自己设置为未定义的行为?

它似乎有效,但我想知道我是否应该选择它using byte = unsigned char;,这会导致其他并发症(例如,我无法区分 byte 和uint8_t)。

c++ strict-aliasing language-lawyer c++14 std-byte

5
推荐指数
1
解决办法
182
查看次数

字节类型:std::byte vs std::uint8_t vs unsigned char vs char vs std::bitset&lt;8&gt;

C++ 有很多类型模糊地描述相同的事物。假设我们正在针对一个字节为 8 位的架构进行编译,则以下所有类型都大致相似:

  • std::byte
  • std::uint8_t
  • std::bitset<8>
  • unsigned char(8 位)
  • char(8 位)

如果一个字节是 8 位,那么所有这些类型或多或少可以互换吗?如果没有,什么时候需要使用一个而不是另一个?

我经常在 Stack Overflow 上看到诸如将十六进制字符串转换为字节数组之类的问题,其中有人使用std::uint8_tcharunsigned char其他类型来表示“字节”。这只是风格偏好的问题吗?


注意:此问答旨在成为社区常见问题解答,鼓励进行编辑。std::byte尽管 C++17 已经引入了这似乎使得选择变得显而易见,但何时使用“字节”的类型以及为什么的问题始终出现。std::bitset提供一个常见问题解答来解决有关、std::uint8_t等作为“字节”的所有误解是很有用的。鼓励编辑。

c++ byte c++17 std-byte

4
推荐指数
1
解决办法
933
查看次数

std::byte 构造函数是否从整数中提取 LSB 或 MSB?

我正在努力理解以下代码行:

if constexpr (std::is_same_v<T, bool>)
{
    std::byte change = std::byte(static_cast<uint32_t>(in) << m_addr[1]);
    std::byte mask = ~std::byte(1u << m_addr[1]);
    dataBlock[m_addr[0]] = (dataBlock[m_addr[0]] & mask) | change;
}
Run Code Online (Sandbox Code Playgroud)

其中dataBlock是 a std::vector<std::byte>Tin的类型,并且m_addr是 a std::array<std::byte, 2>。这会进行位移位以便将 bool 值存储在字节内。我的问题是关于声明中的第一行if。对于此示例,我将使用in = 1m_addr[1] = 3

根据我的理解,static_cast<uint32_t>(in)创建了一个uint32_t给定的00000000,00000000,00000000,00000001; 左移运算符将其转换为00000000,00000000,00000000,00001000,然后将其转换为std::byte

如何std::byte选择存储的字节?我假设它存储 LSB,所以00001000,但我找不到任何参考资料来证实这一点。它可以存储MSB(所以00000000)吗?如果是,我怎样才能使下面的实现平台无关?

c++ c++17 std-byte

3
推荐指数
1
解决办法
121
查看次数

std::is_enum_v&lt;std::byte&gt; 计算结果为 true

根据标准参考std::is_enum_v枚举类型的计算结果为 true,否则为 false。枚举类型以枚举键开头,即枚举、枚举类或枚举结构之一。

编写了以下测试程序:

#include <type_traits>
#include <iostream>

using to_examine = std::byte;

enum class Foo {
    ONE,
    TWO 
};

int main() {
    if constexpr (std::is_enum_v<std::byte>) {
        std::cout << "byte counts as enum" << std::endl;
    }   

    if constexpr(std::is_enum_v<int>) {
        std::cout << "int counts as enum" << std::endl;
    }   

    if constexpr(std::is_enum_v<Foo>) {
        std::cout << "scoped enum counts as enum" << std::endl;
    }   
}
Run Code Online (Sandbox Code Playgroud)

打印出以下内容:

byte counts as enum
scoped enum counts as enum
Run Code Online (Sandbox Code Playgroud)

我正在使用 clang15 和 …

c++ enums type-traits std-byte

2
推荐指数
1
解决办法
166
查看次数

为什么我不能 static_cast char* 到 std::byte*?

我知道我可以使用reinterpret_cast,但是我不能从 char 转换为像 std::byte 这样的“通用”类型似乎很奇怪。这只是不幸的错误/限制,还是有原因?

示例

int main(){
    std::string s{"abc"};
    std::byte* ptr  = static_cast<std::byte*>(s.data());
}
Run Code Online (Sandbox Code Playgroud)

c++ c++20 std-byte

1
推荐指数
1
解决办法
260
查看次数

如何在 C++ 中创建类似于 std::byte 的八位字节类型?

类型由位std::byte组成CHAR_BIT,并且可以多于8位。

那么,如何在 C++ 中声明真正的八位字节?

c++ bit std-byte

1
推荐指数
1
解决办法
128
查看次数