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

You're missing the point why std::byte was invented in the first place. The reason it was invented is to hold a raw byte in memory without the assumption that it's a character. You can see that in cppreference.

Like char and unsigned char, it can be used to access raw memory occupied by other objects (object representation), but unlike those types, it is not a character type and is not an arithmetic type.

Remember that C++ is a strongly typed language in the interest of safety (so implicit conversions are restricted in many cases). Meaning: If an implicit conversion from byte to char was possible, it would defeat the purpose.

So, to answer your question: To use it, you have to cast it whenever you want to make an assignment to 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, by design! So that transform is ugly, agreed, but if you want to store chars, then use char. Don't use bytes unless you want to store raw memory that should not be interpreted as char by default.

And also the last part of your question is generally incorrect: You don't have to make copies, because you don't have to copy the whole vector. If you temporarily need to read a byte as a char, simply static_cast it at the place where you need to use it as a char. It costs nothing, and is type-safe.


As to your question in the comment about casting std::vector<char> to std::vector<std::byte>, you can't do that. But you can use the raw array underneath. So, the following has a type (char*):

std::vector<std::byte> bytes;
// fill it...
char* charBytes = reinterpret_cast<char*>(bytes.data()); 

This has type char*, which is a pointer to the first element of your array, and can be dereferenced without copying, as follows:

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

And the size you get from bytes.size(). This is valid, since std::vector is contiguous in memory. You can't generally do this with any other std container (deque, list, etc...).

While this is valid, it removes part of the safety from the equation, keep that in mind. If you need char, don't use byte.

Tags:

C++

Vector

C++17