我可以不复制就将std :: vector <char>重新解释为std :: vector <unsigned char>吗?

ser*_*rup 5 c++ stdvector reinterpret-cast

我有一个引用std::vector<char>,希望将其用作接受函数的参数std::vector<unsigned char>。我可以不复制就做吗?

我有以下功能,它可以工作;但是我不确定是否真的要进行复制-有人可以帮我理解吗?是否std::move可以避免复制或是否尚未复制?

static void showDataBlock(bool usefold, bool usecolor,
            std::vector<char> &chunkdata)  
{
  char* buf = chunkdata.data();                      
  unsigned char* membuf = reinterpret_cast<unsigned char*>(buf); 
  std::vector<unsigned char> vec(membuf, membuf + chunkdata.size()); 
  showDataBlock(usefold, usecolor, vec);   
} 
Run Code Online (Sandbox Code Playgroud)

我以为我可以写:

std::vector<unsigned char> vec(std::move(membuf),
                               std::move(membuf) + chunkdata.size());  
Run Code Online (Sandbox Code Playgroud)

这是过度杀伤力吗?实际发生了什么?

bol*_*lov 5

如果您有一个v1of 类型std::vector<T1>并且需要一个v2of 类型std::vector<T2>,则无法复制数据,即使 T1 和 T2 像 和 一样“相似charunsigned char

使用标准库:

std::vector<unsigned char> v2;
std::copy(v1.begin(), v1.end(), std::back_inserter(v2));
Run Code Online (Sandbox Code Playgroud)

唯一可能的方法是以某种方式仅使用一种类型:如果std::vector<T2>可能的话从一开始就获取,或者从现在开始使用std::vector<T1>(也许添加一个处理它的重载)。或者创建可以处理任何[连续]容器的通用代码(模板)。


我认为 reinterpret_cast 和 std::move 应该可以避免复制
,不,不
能详细说明 - 为什么不呢?

向量只能从相同类型的另一个向量窃取资源(移动数据)。这就是它的界面的设计方式。

要执行您想要的操作,您需要一个 release() 方法,该方法将释放基础数据的向量所有权并将其作为(唯一)指针返回,以及一个移动构造函数/赋值,该方法将从(唯一)指针获取基础数据。(即便如此,你仍然需要一个reinterpret_cast……危险区域)

std::vector这些都没有。也许应该有。事实并非如此。


Whi*_*TiM 5

...是否可以使用std :: move避免复制,或者是否尚未复制

您不能在两个不相关的容器之间移动。一个std::vector<char>不是一个std::vector<unsigned char>。因此,没有合法的方法可以在O(1)时间内一个内容转换为另一个内容。

您可以复制:

void showData( std::vector<char>& data){
    std::vector<unsigned char> udata(data.begin(), data.end());
    for(auto& x : udata)
        modify( x );
    ....
}
Run Code Online (Sandbox Code Playgroud)

或为每次访问实时投射...

inline unsigned char& as_uchar(char& ch){
    return reinterpret_cast<unsigned char&>(ch);
}

void showDataBlock(std::vector<char>& data){
    for(auto& x : data){
        modify( as_uchar(x) );
    }
}
Run Code Online (Sandbox Code Playgroud)