Search code examples
c++stdvectorreinterpret-cast

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?


Solution

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