[英]How to convert unsigned char[] to std::vector<unsigned char>
[英]How to convert std::vector<unsigned char> to vector<char> without copying?
我无法找到这个问题,这是我面临的一个实际问题。
我有一个文件加载实用程序,它返回包含整个文件内容的std::vector<unsigned char>
。 但是,处理函数需要contiguos char
数组(并且不能更改 - 它是库函数)。 由于使用处理函数的类仍然存储数据的副本,我想将其存储为vector<char>
。 这里的代码可能更具说明性。
std::vector<unsigned char> LoadFile (std::string const& path);
class Processor {
std::vector<char> cache;
void _dataOperation(std::vector<char> const& data);
public:
void Process() {
if (cache.empty())
// here's the problem!
cache = LoadFile("file.txt");
_dataOperation(cache);
}
};
此代码无法编译,因为(显然)没有适当的转换。 但是,我们可以肯定,临时向量将占用相同数量的内存(IOW sizeof(char) == sizeof(unsigned char)
)
天真的解决方案是迭代临时内容并投射每个角色。 我知道在正常情况下,将调用operator= (T&&)
。
在我的情况下,重新解释转换是安全的,因为我确信我只会读取ASCII字符。 无论如何,任何其他角色都会被_dataOperation
捕获。
所以,我的问题是: 如何以一种不涉及复制的方式正确安全地转换临时向量?
如果不可能,我宁愿采用安全的复制方式而不是不安全的非复制方式。 我还可以更改LoadFile
以返回vector<char>
或vector<unsigned char>
。
在C ++ 11中,[basic.lval] p10说,
如果程序试图通过以下类型之一以外的glvalue访问对象的存储值,则行为未定义:
- ...
- char或unsigned char类型。
(其他版本的C ++中的确切位置可能不同,但含义相同。)
这意味着您可以使用vector<unsigned char> cache
并使用范围[reinterpret_cast<char*>(cache.data()), reinterpret_cast<char*>(cache.data()) + cache.size())
访问其内容[reinterpret_cast<char*>(cache.data()), reinterpret_cast<char*>(cache.data()) + cache.size())
。 (@Kerrek SB提到了这一点。)
如果在Processor
存储vector<unsigned char>
以匹配LoadFile
的返回类型,并且_dataOperation()
实际上采用char
数组(意味着const char*
和size),那么您可以在传递_dataOperation()
参数
但是,如果_dataOperation()
专门采用vector<char>
并存储vector<unsigned char> cache
,则无法将其传递给reinterpret_cast<vector<char>&>(cache)
。 (即@AndréPuel完全错了。不要听他说。)这违反了别名规则,编译器会在凌晨2点试图激怒你的客户。 (如果这个版本的编译器没有管理它,下一个版本将继续尝试。)
正如您所提到的,一个选项是模板LoadFile()
并让它返回(或填充)您想要的类型的向量。 另一种方法是复制结果,简洁版本再次是源向量的.data()
的reinterpret_cast
。 [basic.fundamental] p1提到“对于字符类型,对象表示的所有位都参与值表示。”,这意味着您不会丢失使用该reinterpret_cast
数据。 我没有看到一个确定的保证,如果reinterpret_cast'ed
为char
,没有unsigned char
位模式可能导致陷阱,但我不知道有任何现代硬件或编译器这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.