Dank Lincolns Kommentar unten habe ich diese Antwort geändert.
Die folgende Antwort behandelt 8-Bit-Ints zur Kompilierungszeit ordnungsgemäß. Es erfordert jedoch C ++ 17. Wenn Sie nicht über C ++ 17 verfügen, müssen Sie etwas anderes tun (z. B. Überladungen dieser Funktion bereitstellen, eine für uint8_t und eine für int8_t, oder etwas anderes als "if constexpr" verwenden, möglicherweise enable_if).
template< typename T >
std::string int_to_hex( T i )
{
// Ensure this function is called with a template parameter that makes sense. Note: static_assert is only available in C++11 and higher.
static_assert(std::is_integral<T>::value, "Template argument 'T' must be a fundamental integer type (e.g. int, short, etc..).");
std::stringstream stream;
stream << "0x" << std::setfill ('0') << std::setw(sizeof(T)*2) << std::hex;
// If T is an 8-bit integer type (e.g. uint8_t or int8_t) it will be
// treated as an ASCII code, giving the wrong result. So we use C++17's
// "if constexpr" to have the compiler decides at compile-time if it's
// converting an 8-bit int or not.
if constexpr (std::is_same_v<std::uint8_t, T>)
{
// Unsigned 8-bit unsigned int type. Cast to int (thanks Lincoln) to
// avoid ASCII code interpretation of the int. The number of hex digits
// in the returned string will still be two, which is correct for 8 bits,
// because of the 'sizeof(T)' above.
stream << static_cast<int>(i);
}
else if (std::is_same_v<std::int8_t, T>)
{
// For 8-bit signed int, same as above, except we must first cast to unsigned
// int, because values above 127d (0x7f) in the int will cause further issues.
// if we cast directly to int.
stream << static_cast<int>(static_cast<uint8_t>(i));
}
else
{
// No cast needed for ints wider than 8 bits.
stream << i;
}
return stream.str();
}
Ursprüngliche Antwort, die 8-Bit-Ints nicht richtig verarbeitet, wie ich dachte:
Die Antwort von Kornel Kisielewicz ist großartig. Ein kleiner Zusatz hilft jedoch dabei, Fälle zu erfassen, in denen Sie diese Funktion mit Vorlagenargumenten aufrufen, die keinen Sinn ergeben (z. B. float) oder die zu unordentlichen Compilerfehlern führen würden (z. B. benutzerdefinierter Typ).
template< typename T >
std::string int_to_hex( T i )
{
// Ensure this function is called with a template parameter that makes sense. Note: static_assert is only available in C++11 and higher.
static_assert(std::is_integral<T>::value, "Template argument 'T' must be a fundamental integer type (e.g. int, short, etc..).");
std::stringstream stream;
stream << "0x"
<< std::setfill ('0') << std::setw(sizeof(T)*2)
<< std::hex << i;
// Optional: replace above line with this to handle 8-bit integers.
// << std::hex << std::to_string(i);
return stream.str();
}
Ich habe dies bearbeitet, um std :: to_string einen Aufruf hinzuzufügen, da 8-Bit-Integer-Typen (z. B. übergebene std::uint8_t
Werte) std::stringstream
als char behandelt werden, wodurch Sie nicht das gewünschte Ergebnis erhalten. Das Übergeben solcher Ganzzahlen, std::to_string
um sie korrekt zu behandeln, schadet nichts, wenn andere, größere Ganzzahltypen verwendet werden. Natürlich kann es in diesen Fällen zu einem leichten Leistungseinbruch kommen, da der Aufruf von std :: to_string nicht erforderlich ist.
Hinweis: Ich hätte dies nur in einem Kommentar zur ursprünglichen Antwort hinzugefügt, aber ich habe nicht den Repräsentanten, um einen Kommentar abzugeben.
int
Typ;)