简体   繁体   English

我可以重新解释std :: vector <char> 作为std :: vector <unsigned char> 没有复制?

[英]Can I reinterpret std::vector<char> as a std::vector<unsigned char> without copying?

I have a reference to std::vector<char> that I want to use as a parameter to a function which accepts std::vector<unsigned char> . 我有一个std::vector<char>的引用,我想用它作为接受std::vector<unsigned char>的函数的参数。 Can I do this without copying? 我可以不复制吗?

I have following function and it works; 我有以下功能,它的工作原理; however I am not sure if a copy actually takes place - could someone help me understanding this? 但我不确定副本是否真的发生 - 有人可以帮助我理解这个吗? Is it possible to use std::move to avoid copy or is it already not being copied? 是否可以使用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);   
} 

I was thinking that I could write: 我以为我可以写:

std::vector<unsigned char> vec(std::move(membuf),
                               std::move(membuf) + chunkdata.size());  

Is this overkill? 这有点矫枉过正吗? What actually happens? 究竟发生了什么?

...is it possible to use std::move to avoid copy or is it already not being copied ...是否可以使用std :: move来避免复制,或者它是否已被复制

You cannot move between two unrelated containers. 您不能在两个不相关的容器之间移动。 a std::vector<char> is not a std::vector<unsigned char> . std::vector<char> 不是 std::vector<unsigned char> And hence there is no legal way to "move ~ convert" the contents of one to another in O(1) time. 因此,没有合法的方法在O(1)时间内一个内容“移动〜转换”到另一个内容。

You can either copy: 你可以复制:

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

or cast it in realtime for each access... 或者为每次访问实时投射......

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) );
    }
}

I guess you coded another overloaded function :- 我猜你编码了另一个重载函数: -

showDataBlock(usefold, usecolor, std::vector<unsigned char> & vec);  

You try to convert from std::vector<T> to another std::vector<T2> . 您尝试从std::vector<T>转换为另一个std::vector<T2>

There is no way to avoid the copying . 没有办法避免复制

Each std::vector has its own storage, roughly speaking, it is a raw pointer. 每个std::vector都有自己的存储空间,粗略地讲,它是一个原始指针。
The main point is : you can't share such raw pointer among multiple std::vector . 重点是:你不能在多个std::vector共享这样的原始指针。
I think it is by design. 我认为这是设计的。
I think it is a good thing, otherwise it would waste CPU to keep track. 我认为这是一件好事,否则会浪费CPU来跟踪。

The code ... 编码 ...

std::move(membuf)

... move the raw pointer = actually do nothing. ...移动原始指针=实际上什么都不做。 (same as passing as membuf ) (与传递为membuf相同)

To optimize, you should verify the reason : why you want to convert from std::vector<char> to std::vector<unsigned char> in the first place. 要进行优化,您应该验证原因:首先要将std::vector<char>转换为std::vector<unsigned char>

Is it a better idea if you create a new class C that can represent as both char and unsigned char ? 如果你创建一个可以表示charunsigned char的新类C ,这是一个更好的主意吗? (eg C::getChar() and C::getUnsignedChar() , may be ... store only char but provide converter as its non-static function) (例如C::getChar()C::getUnsignedChar() ,可能是......只存储char但提供转换器作为其非静态函数)

If it doesn't help, I suggest creating a new custom data-structure. 如果它没有帮助,我建议创建一个新的自定义数据结构。
I often do that when it is needed. 我经常在需要时这样做。

However, in this case, I don't think it need any optimization. 但是,在这种情况下,我认为不需要任何优化。
It is OK for me, except it is a performance critical code. 对我来说没关系,除非它是性能关键代码。

If you have a v1 of type std::vector<T1> and need a v2 of type std::vector<T2> there is no way around copying the data, even if T1 and T2 are "similar" like char and unsigned char . 如果你有一个类型为std::vector<T1>v1并且需要一个类型为std::vector<T2>v2 ,那么即使T1和T2像charunsigned char一样“相似”,也无法复制数据。 。

Use standard library: 使用标准库:

std::vector<unsigned char> v2;
std::copy(v1.begin(), v1.end(), std::back_inserter(v2));

The only possible way around it is to somehow work with only one type: either obtain std::vector<T2> from the start if possible, or work with std::vector<T1> from now on (maybe add an overload that deals with it). 唯一可行的方法是以某种方式只使用一种类型:如果可能的话,从一开始就获取std::vector<T2> ,或者从现在开始使用std::vector<T1> (可能会添加一个超载用它)。 Or create generic code (templates) that can deal with any [contigous] container. 或者创建可以处理任何[contigous]容器的通用代码(模板)。


I think reinterpret_cast and std::move should make it possible to avoid copy 我认为reinterpret_cast和std :: move应该可以避免复制
no, it can't 不,它不能
please elaborate - why not? 请详细说明 - 为什么不呢?

A vector can steal resources (move data) only from another vector of the same type. 矢量可以仅从相同类型的另一个矢量中窃取资源(移动数据)。 That's how it's interface was designed. 这就是它的界面设计方式。

To do what you want you would need a release() method that would release the vector ownership of the underlying data and return it as a (unique) pointer and a move constructor/assignment that would acquire the underlying data from a (unique) pointer. 要做你想做的事,你需要一个release()方法,它将释放底层数据的向量所有权并将其作为(唯一)指针和移动构造函数/赋值返回,它将从(唯一)指针获取底层数据。 (And even then you would still require an reinterpret_cast which is... danger zone) (即便如此,你仍然需要一个reinterpret_cast ,这是......危险区域)

std::vector has none of those. std::vector没有这些。 Maybe it should have. 也许应该有。 It just doesn't. 它只是没有。

As others already pointed out, there is no way around the copy without changing showDataBlock . 正如其他人已经指出的那样,如果不改变showDataBlock ,就无法绕过副本。

I think you have two options: 我想你有两个选择:

  1. Extend showDataBlock to work on both signed char and unsigned char (ie. make it a template) or 扩展showDataBlock以处理signed charunsigned char (即使其成为模板)或
  2. Don't take the container as argument but an iterator range instead. 不要将容器作为参数,而是使用迭代器范围。 You could then (in case of value_type being char ) use special iterators converting from signed char to unsigned char elementwisely. 然后,您可以(在value_typechar情况下)使用特殊迭代器从signed char转换为unsigned char元素。

while unsigned char and char are unrelated types. unsigned charchar是不相关的类型。 I think they're similar enough in this case (same size pods) to get away with a reinterpret_cast of the entire templated class. 我认为它们在这种情况下(相同大小的pod)足够相似,以逃避整个模板类的reinterpret_cast。

static void showDataBlock(bool usefold, bool usecolor,
            std::vector<char> &chunkdata)  
{
  showDataBlock(usefold, usecolor, reinterpret_cast< std::vector<unsigned char>&>(chunkdata));   
}

However, I tend to find these problems are due to not designing the best architecture. 但是,我倾向于发现这些问题是由于没有设计出最好的架构。 Look at the bigger picture of what it is that this software is supposed to be doing to identify why you need to work wit both signed and unsigned char blocks of data. 看看这个软件应该做的更大的图片,以确定为什么你需要使用有符号和无符号的char数据块。

I ended up doing something like this : 我最终做了这样的事情:

static void showDataBlock(bool usefold,bool usecolor, std::vector<char> chunkdata)
{                                                                                                                           
    std::vector<unsigned char>&cache = reinterpret_cast<std::vector<unsigned char>&>(chunkdata);                                              
    showDataBlock(usefold, usecolor, cache);    
}                                                                             

static bool showDataBlock(bool usefold,bool usecolor, std::vector<unsigned char> &chunkdata)   
{
    // showing the data
}

This solution allowed me to pass vector as ref or as normal it seems to be working - if its the best solution I do not know, however you all came with some really good suggestions - thank you all 这个解决方案允许我传递矢量作为参考或正常它似乎工作 - 如果它是我不知道的最佳解决方案,但是你们都带来了一些非常好的建议 - 谢谢大家

I agree I can not avoid the copy, so I let the copy be done with normal parameter passing 我同意我无法避免副本,所以我让副本通过正常参数传递完成

Please if you find this solution wrong, then provide a better one in comment, not just downvote 如果您发现此解决方案有误,请在评论中提供更好的解决方案,而不仅仅是downvote

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何转换std :: vector <unsigned char> 矢量 <char> 没有复制? - How to convert std::vector<unsigned char> to vector<char> without copying? 我该如何投射一个std :: vector <const unsigned char> 到const std :: vector <unsigned char> ? - How can I cast an std::vector<const unsigned char> to a const std::vector<unsigned char>? 我怎样才能转换const std :: vector <unsigned char> 去char - How can I convert const std::vector<unsigned char> to char unsigned char std :: vector to unsigned char []? - Unsigned char std::vector to unsigned char[]? 的std ::矢量 <unsigned char> 到QPixmap - std::vector<unsigned char> to QPixmap Cast const std :: vector <char> 到unsigned char *? - Cast const std::vector<char> to unsigned char*? 复制 std::vector<unsigned char> 使用 memcpy 取消 * 缓冲区 - copying std::vector<unsigned char> to void * buffer using memcpy std :: vector &lt;std :: vector <unsigned char> &gt;或std :: deque &lt;std :: vector <unsigned char> &gt;? - std::vector< std::vector<unsigned char> > or std::deque< std::vector<unsigned char> >? 如何将`std :: string`转换为`std :: vector <unsigned char> `没有复制? - How do I cast `std::string` to `std::vector<unsigned char>` without making a copy? 分配 std::vector<std::byte> 到 std::vector<char> 不复制 memory</char></std::byte> - Assign std::vector<std::byte> to std::vector<char> WITHOUT copying memory
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM