我找不到那个问题,这是我面临的实际问题。
我有一个文件加载实用程序,它返回 std::vector<unsigned char>
包含整个文件内容。
但是,处理函数需要 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);
}
};
此代码无法编译,因为(显然)没有适当的转换。但是,我们可以肯定,临时 vector 将占用相同数量的内存(IOW sizeof(char) == sizeof(unsigned char)
)
天真的解决方案是遍历临时的内容并强制转换每个字符。我知道在正常情况下,operator= (T&&)
会被调用。
在我的情况下,重新解释转换是安全的,因为我确信我只会读取 ASCII 字符。任何其他角色都会被 _dataOperation
捕获。无论如何。
所以,我的问题是:如何以不涉及复制的方式正确安全地转换临时 vector ?
如果不可能,我更喜欢安全的复制方式,而不是不安全的非复制方式。我也可以更改LoadFile
返回 vector<char>
或 vector<unsigned char>
.
最佳答案
在 C++11 中,[basic.lval]p10 表示,
If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined:
- ...
- a char or unsigned char type.
(具体位置在其他版本的C++中可能不同,但含义相同。)
这意味着您可以使用 vector<unsigned char> cache
并使用范围 [reinterpret_cast<char*>(cache.data()), reinterpret_cast<char*>(cache.data()) + cache.size())
访问其内容. (@Kerrek SB 提到了这一点。)
如果您存储 vector<unsigned char>
在 Processor
匹配 LoadFile
的返回类型, 和 _dataOperation()
实际上需要一个数组 char
(表示 const char*
和大小),那么您可以在将参数传递给 _dataOperation()
时进行转换
但是,如果 _dataOperation()
需要 vector<char>
具体来说,您存储了 vector<unsigned char> cache
,那么你不能通过reinterpret_cast<vector<char>&>(cache)
. (即@André Puel 是完全错误的。不要听他的。)这违反了别名规则,编译器会在凌晨 2 点试图激怒你的客户。 (如果这个版本的编译器不能管理它,下一个版本会继续尝试。)
正如您提到的,一个选项是模板 LoadFile()
并让它返回(或填充)您想要的类型的 vector 。另一种是复制结果,其简洁版本再次为reinterpret_cast
。源 vector 的.data()
. [basic.fundamental]p1 提到“对于字符类型,对象表示的所有位都参与值表示。”,这意味着您不会因为 reinterpret_cast
而丢失数据。 .我没有看到一个坚定的保证 unsigned char
没有位模式如果 reinterpret_cast'ed
会导致陷阱至char
,但我不知道有任何现代硬件或编译器可以做到这一点。
关于c++ - 如何在不复制的情况下将 std::vector<unsigned char> 转换为 vector<char>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14719529/