I understand that this is an old question, but it is also a true Google result in finding a solution to a very similar problem that I have, which is the desire to implement an arbitrary integer with hexadecimal string conversions in the template class. My final goal was actually a template subclass of Gtk::Entry that would allow editing various integer widths in hexadecimal format, but this is next to the dot.
This combines the operator+ unary trick with std::make_unsigned from <type_traits> to prevent the problem of meaningful negative int8_t or signed char values ββthat occur in this answer
In any case, I think this is more eloquent than any other general solution. It should work for any signed or unsigned integer types and throws a compile-time error if you try to instantiate a function with any non-integer types.
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(); }
Example usage example:
int main(int argc, char**argv) { int16_t val; // Prints 'ff' instead of "ffffffff". Unlike the other answer using the '+' // operator to extend sizeof(char) int types to int/unsigned int std::cout << toHexString(int8_t(-1)) << std::endl; // Works with any integer type std::cout << toHexString(int16_t(0xCAFE)) << std::endl; // You can use setw and setfill with strings too -OR- // the toHexString could easily have parameters added to do that. std::cout << std::setw(8) << std::setfill('0') << toHexString(int(100)) << std::endl; return 0; }
Update: Alternatively, if you do not like the idea of ββusing ostringstream , you can combine the template and unary operator trick with the decision made based on the answer to the following. Please note that here I changed the template, removing the check for integer types. Using make_unsigned might be enough to provide security like compile time.
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); }
Brian McFarland Mar 13 '16 at 4:54 on 2016-03-13 04:54
source share