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::EntryUnterklassenvorlage, 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_unsignedvon <type_traits>, um das Problem des vorzeichenverlängernden Negativs int8_toder signed charder 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 ostringstreamVerwendung 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_unsignedVerwendung 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;