c++ - 如何在不复制的情况下将 std::vector<unsigned char> 转换为 vector<char>?

标签 c++ vector std

我找不到那个问题,这是我面临的实际问题。

我有一个文件加载实用程序,它返回 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/

相关文章:

c++ - C++ 中类原型(prototype)的问题

c++ - 创建和管理查找容器的正确方法

c++ - 异步传递时如何在函数中传递多个参数

c++ - std::stringstream 中双输出的默认格式标志(和宽度)是什么?

c++ - std::locale::global 对 printf() 函数有影响吗?

c++ - OpenMP 嵌套 for 循环(使用 Qt)

r - 按特定(自定义)顺序对整数向量进行排序

android - 更新将 vectorDrawables 与 androidx 一起使用

vector - 用于处理 2D vector 和坐标的库

c++ - std::vector 差异