Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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>. 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?

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?

like image 656
serup Avatar asked Jan 04 '17 11:01

serup


1 Answers

...is it possible to use std::move to avoid copy or is it already not being copied

You cannot move between two unrelated containers. a std::vector<char> is not a std::vector<unsigned char>. And hence there is no legal way to "move ~ convert" the contents of one to another in O(1) time.

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) );
    }
}
like image 160
WhiZTiM Avatar answered Oct 02 '22 14:10

WhiZTiM