gpt4 book ai didi

c++ - 如何在需要旧式 unsigned char 的地方使用新的 std::byte 类型?

转载 作者:IT老高 更新时间:2023-10-28 12:50:47 27 4
gpt4 key购买 nike

std::byte是 C++17 中的一种新类型,被制成 enum class byte : unsigned char .这使得在没有适当转换的情况下无法使用它。所以,我为这种类型的 vector 取了一个别名来表示一个字节数组:

using Bytes = std::vector<std::byte>;

但是,它不可能在旧式中使用:接受它作为参数的函数会失败,因为这种类型不能轻易转换为旧式 std::vector<unsigned char>键入,例如 zipper 的用法图书馆:

/resourcecache/pakfile.cpp: In member function 'utils::Bytes resourcecache::PakFile::readFile(const string&)':
/resourcecache/pakfile.cpp:48:52: error: no matching function for call to 'zipper::Unzipper::extractEntryToMemory(const string&, utils::Bytes&)'
unzipper_->extractEntryToMemory(fileName, bytes);
^
In file included from /resourcecache/pakfile.hpp:13:0,
from /resourcecache/pakfile.cpp:1:
/projects/linux/../../thirdparty/zipper/zipper/unzipper.h:31:10: note: candidate: bool zipper::Unzipper::extractEntryToMemory(const string&, std::vector<unsigned char>&)
bool extractEntryToMemory(const std::string& name, std::vector<unsigned char>& vec);
^~~~~~~~~~~~~~~~~~~~
/projects/linux/../../thirdparty/zipper/zipper/unzipper.h:31:10: note: no known conversion for argument 2 from 'utils::Bytes {aka std::vector<std::byte>}' to 'std::vector<unsigned char>&'

我曾尝试执行幼稚的 Actor 阵容,但这也无济于事。那么,如果它被设计成有用的,它在旧环境中真的有用吗?我看到的唯一方法是使用 std::transform在这些地方使用新的字节 vector :

utils::Bytes bytes;
std::vector<unsigned char> rawBytes;
unzipper_->extractEntryToMemory(fileName, rawBytes);
std::transform(rawBytes.cbegin(),
rawBytes.cend(),
std::back_inserter(bytes),
[](const unsigned char c) {
return static_cast<std::byte>(c);
});
return bytes;

这是:

  1. 丑。
  2. 占用了很多无用的行(可以重写,但还是需要先写:))。
  3. 复制内存,而不是仅使用已创建的 rawBytes block .

那么,老地方怎么用呢?

最佳答案

你错过了 std::byte 的原因是最早发明的。发明它的原因是在内存中保存一个原始字节而不假设它是一个字符。您可以在 cppreference 中看到.

Like char and unsigned char, it can be used to access raw memory occupied by other objects (object representation), but unlike those types, it is not a character type and is not an arithmetic type.

请记住,为了安全起见,C++ 是一种强类型语言(因此在许多情况下隐式转换受到限制)。含义:如果从 byte 进行隐式转换至char是可能的,它会破坏目的。

所以,要回答您的问题:要使用它,您必须在要对其进行分配时对其进行转换:

std::byte x = (std::byte)10;
std::byte y = (std::byte)'a';
std::cout << (int)x << std::endl;
std::cout << (char)y << std::endl;

按照设计,其他任何方法都不起作用!所以这个转换是丑陋的,同意,但如果你想存储字符,那么使用 char .不要使用字节,除非您想存储不应被解释为 char 的原始内存默认情况下

而且您问题的最后一部分通常是不正确的:您不必复制,因为您不必复制整个 vector 。如果您暂时需要阅读 byte作为 char , 简单的 static_cast它在您需要使用它的地方作为char .它不花钱,而且是类型安全的。


至于您在关于类型转换 std::vector<char> 的评论中提出的问题至 std::vector<std::byte> ,你不能那样做。但是您可以使用下面的原始数组。所以,下面有一个类型 (char*) :

std::vector<std::byte> bytes;
// fill it...
char* charBytes = reinterpret_cast<char*>(bytes.data());

这有类型 char* ,它是指向数组第一个元素的指针,可以在不复制的情况下取消引用,如下所示:

std::cout << charBytes[5] << std::endl; //6th element of the vector as char

还有你从​​ bytes.size() 得到的大小.这是有效的,因为 std::vector在内存中是连续的。您通常不能对任何其他标准容器(双端队列、列表等)执行此操作。

虽然这是有效的,但它从等式中删除了部分安全性,请记住这一点。如果您需要char , 不要使用 byte .

关于c++ - 如何在需要旧式 unsigned char 的地方使用新的 std::byte 类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46150738/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com