c++ - How to use new std::byte type in places where old-style unsigned char is needed? -


std::byte new type in c++17 made enum class byte : unsigned char. makes impossible use without appropriate conversion. so, have made alias vector of such type represent byte array:

using bytes = std::vector<std::byte>; 

however, impossible use in old-style: functions accept parameter fail because type can not converted old std::vector<unsigned char> type, example, usage of zipper library:

/resourcecache/pakfile.cpp: in member function 'utils::bytes resourcecache::pakfile::readfile(const string&)': /resourcecache/pakfile.cpp:48:52: error: no matching function call 'zipper::unzipper::extractentrytomemory(const string&, utils::bytes&)'      unzipper_->extractentrytomemory(filename, bytes);                                                     ^ in file included /resourcecache/pakfile.hpp:13:0,                  /resourcecache/pakfile.cpp:1: /projects/linux/../../thirdparty/zipper/zipper/unzipper.h:31:10: note: candidate: bool zipper::unzipper::extractentrytomemory(const string&, std::vector<unsigned char>&)      bool extractentrytomemory(const std::string& name, std::vector<unsigned char>& vec);           ^~~~~~~~~~~~~~~~~~~~ /projects/linux/../../thirdparty/zipper/zipper/unzipper.h:31:10: note:   no known conversion argument 2 'utils::bytes {aka std::vector<std::byte>}' 'std::vector<unsigned char>&' 

i have tried perform naive casts not also. so, if designed useful, useful in old contexts? method see use std::transform using new vector of bytes in these places:

utils::bytes bytes; std::vector<unsigned char> rawbytes; unzipper_->extractentrytomemory(filename, rawbytes); std::transform(rawbytes.cbegin(),                rawbytes.cend(),                std::back_inserter(bytes),                [](const unsigned char c) {                    return static_cast<std::byte>(c);                }); return bytes; 

which is:

  1. ugly.
  2. takes lot of useless lines (can rewritten still needs written before:)).
  3. copies memory instead of using created chunk of rawbytes.

so, how use in old places?

you're missing point why std::byte invented in first place. reason invented hold raw byte in memory without assumption it's character. can see in cppreference.

like char , unsigned char, can used access raw memory occupied other objects (object representation), unlike types, not character type , not arithmetic type.

remember c++ typed language in intrest of safety (so implicit conversions restricted in many cases). meaning: if implicit conversion byte char possible, defeat purpose.

so, answer question: use it, have cast whenever want make assignment it:

std::byte x = (std::byte)10; std::byte y = (std::byte)'a'; std::cout << (int)x << std::endl; std::cout << (char)y << std::endl; 

anything else shall not work, design! transform ugly, agreed, if want store chars, use char. don't use bytes unless want store raw memory that should not interpreted char default.

and last part of question incorrect: don't have make copies, because don't have copy whole vector. if temporarily need read byte char, static_cast @ place need use char. costs nothing, , type-safe.


question in comment casting std::vector<char> std::vector<std::byte>, can't that. can use raw array underneath. so, following has type (char*):

std::vector<std::byte> bytes; //fill it... char* charbytes = static_cast<char*>(&bytes.front());  

this has type char*, pointer first element of array, , can dereferenced without copying, follows:

std::cout << charbytes[5] << std::endl; //6th element of vector char 

and size bytes.size(). valid, since std::vector contiguous in memory. can't other std container (deque, list, etc...).

while valid, removes part of safety equation, keep in mind. if need char, don't use byte.


Comments

Popular posts from this blog

Sort a complex associative array in PHP -

vb.net - How to ignore if a cell is empty nothing -

recursion - Can every recursive algorithm be improved with dynamic programming? -