std::byte
Ist ein neuer Typ in C++ 17, der als enum class byte : unsigned char
Erstellt wird. Dies macht es unmöglich, es ohne entsprechende Konvertierung zu verwenden. Daher habe ich einen Alias für den Vektor dieses Typs erstellt, der ein Byte-Array darstellt:
using Bytes = std::vector<std::byte>;
Es ist jedoch unmöglich, es im alten Stil zu verwenden: Die Funktionen, die es als Parameter akzeptieren, schlagen fehl, weil dieser Typ nicht einfach in einen alten std::vector<unsigned char>
- Typ konvertiert werden kann, z. B. eine Verwendung von zipper
Bibliothek:
/resourcecache/pakfile.cpp: In member function 'utils::Bytes resourcecache::PakFile::readFile(const string&)':
/resourcecache/pakfile.cpp:48:52: error: no matching function for call to 'zipper::Unzipper::extractEntryToMemory(const string&, utils::Bytes&)'
unzipper_->extractEntryToMemory(fileName, bytes);
^
In file included from /resourcecache/pakfile.hpp:13:0,
from /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 for argument 2 from 'utils::Bytes {aka std::vector<std::byte>}' to 'std::vector<unsigned char>&'
Ich habe versucht, naive Casts durchzuführen, aber das hilft auch nicht. Also, wenn es nützlich sein soll, wird es tatsächlich in alten Kontexten nützlich sein? Die einzige Methode, die ich sehe, ist die Verwendung von std::transform
Für die Verwendung eines neuen Vektor von Bytes an folgenden Stellen:
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;
Welches ist:
rawBytes
zu verwenden.Also, wie benutzt man es an alten Orten?
Wenn Ihr alter Code Bereiche oder Iteratoren als Argumente verwendet, können Sie diese weiterhin verwenden. In den wenigen Fällen, in denen dies nicht möglich ist (z. B. bei auf explicit
Bereichen basierenden Konstruktoren), können Sie theoretisch eine neue Iteratorklasse schreiben, die einen Iterator in unsigned char
Umschließt und *it
Konvertiert. zu std::byte&
.
Wenn Sie möchten, dass sich etwas wie ein Byte so verhält, wie Sie es wahrscheinlich erwarten würden, das jedoch einen anderen Namen trägt als nicht signiertes Zeichen, verwenden Sie uint8_t von stdint.h. Für fast alle Implementierungen wird dies wahrscheinlich ein
typedef unsigned char uint8_t;
und wieder ein unsignierter char unter der haube - aber wen interessiert das schon? Sie möchten nur "Dies ist kein Zeichentyp" hervorheben. Sie müssen einfach nicht damit rechnen, dass einige Funktionen zweimal überladen werden können, eine für unsigned char und eine für uint8_t. Aber wenn Sie das tun, wird der Compiler Ihre Nase trotzdem darauf schieben ...