Mir ist klar, dass dies eine alte Frage ist, aber es ist auch ein Top-Ergebnis von Google bei der Suche nach einer Lösung für ein sehr ähnliches Problem, das ich habe, nämlich den Wunsch, willkürliche Konvertierungen von Ganzzahlen in Hex-Zeichenfolgen innerhalb einer Vorlagenklasse zu implementieren. Mein Endziel war eigentlich eine Gtk::Entry
Unterklassenvorlage, mit der verschiedene ganzzahlige Breiten in hexadezimaler Form bearbeitet werden können, aber das ist nebensächlich.
Dies kombiniert den unären operator+
Trick mit std::make_unsigned
von <type_traits>
, um das Problem des vorzeichenverlängernden Negativs int8_t
oder signed char
der in dieser Antwort auftretenden Werte zu vermeiden
Jedenfalls glaube ich, dass dies prägnanter ist als jede andere generische Lösung. Es sollte für alle vorzeichenbehafteten oder vorzeichenlosen Ganzzahltypen funktionieren und einen Fehler beim Kompilieren auslösen, wenn Sie versuchen, die Funktion mit Nicht-Ganzzahltypen zu instanziieren.
template <
typename T,
typename = typename std::enable_if<std::is_integral<T>::value, T>::type
>
std::string toHexString(const T v)
{
std::ostringstream oss;
oss << std::hex << +((typename std::make_unsigned<T>::type)v);
return oss.str();
}
Einige Anwendungsbeispiele:
int main(int argc, char**argv)
{
int16_t val;
std::cout << toHexString(int8_t(-1)) << std::endl;
std::cout << toHexString(int16_t(0xCAFE)) << std::endl;
std::cout << std::setw(8) << std::setfill('0') <<
toHexString(int(100)) << std::endl;
return 0;
}
Update: Wenn Ihnen die Idee der ostringstream
Verwendung nicht gefällt, können Sie alternativ den Vorlagen- und den unären Operator-Trick mit der strukturbasierten Lösung der akzeptierten Antwort für Folgendes kombinieren. Beachten Sie, dass ich hier die Vorlage geändert habe, indem ich die Prüfung auf Ganzzahltypen entfernt habe. Die make_unsigned
Verwendung kann ausreichen, um Sicherheitsgarantien für den Kompilierungszeittyp zu erstellen.
template <typename T>
struct HexValue
{
T value;
HexValue(T _v) : value(_v) { }
};
template <typename T>
inline std::ostream& operator<<(std::ostream& o, const HexValue<T>& hs)
{
return o << std::hex << +((typename std::make_unsigned<T>::type) hs.value);
}
template <typename T>
const HexValue<T> toHex(const T val)
{
return HexValue<T>(val);
}
std::cout << toHex(int8_t(-1)) << std::endl;