有没有一种合法的方法可以将 unsigned char 指针转换为 std::byte 指针?

Is there a legal way to convert a unsigned char pointer to std::byte pointer?

我使用 STB library to load images into memory. The specific function, stbi_load,returns 一个指向 unsigned char 的指针,它是一个数组。

我很想对原始数据使用新的 C++17 API,std::byte,这将使我更具表现力,并让我为原始数据像素别名像素,或通过将其转换为不同的数据类型(不同大小的整数)逐个颜色。

现在我尝试了这个:

std::unique_ptr<std::byte[], stbi_deleter>(stbi_load(...));

当然,由于缺少隐式转换,它没有起作用。

然后我试了一下:

std::unique_ptr<std::byte[], stbi_deleter>(
  static_cast<std::byte*>(stbi_load(...))
);

还是不行。我不得不决定改用 reinterpret_cast 。并让我质疑这种转换是否合法。我可以根据严格的别名规则 合法地将 unsigned char* 转换为 std::byte* 吗?然后我可以将数据转换为另一种数据类型,例如 std::uint32_t* 并对其进行变异吗?这也会打破别名规则吗?

严格的别名规则从不禁止任何指针转换。它是关于访问对象的表达式的类型。

std::byte 可以别名任何其他类型,这在您链接的 cppreference 页面中提到,当然在标准中的严格别名规则中提到(C++17 basic.lval/8.8).所以用reinterpret_cast<std::byte *>然后读写unsigned char.

的数组就可以了

如果您使用 uint32_t 类型的表达式来读取或写入 unsigned char 的数组,那将违反严格的别名规则。

Can I legally convert a unsigned char* to std::byte* according to the strict aliasing rule?

是的,这就是 std::byte "inherits" 来自 unsigned char 的具体原因。但是你必须经历 reinterpret_cast<> 就像你将任意类型转换为 char*unsigned char*

一样

And then can I cast the data to another datatype like std::uint32_t* and mutate it.

没有。你不能用 std::byte 做任何你不能用 char*unsigned char*.

做的事情

std::byte 的主要用途似乎是拥有可以同时具有字符串和原始数据重载的函数。

此外,它消除了以下烦恼:

char val = foo();
std::cout << (int)val << "\n";