Background:
I have template stream operators (e.g. operator << (ostream &, std::vector <T>)
) (that output container elements that may possibly be of some 8-bit integer type, (e.g. unsigned char
, int_least8_t
, et cetera).
Problem:
Default is that these types are output as char
(ASCII).
I only used char
(or wchar_t
or whatever) for ASCII variables, never unsigned/signed types.
How do I get these other 8-bit types to always be output as signed int
/ unsigned int
(numbers) instead, even when the caller doesn't know the type?
First tries:
I have tried (with GCC) for example defining operator << (ostream &, unsigned char)
with a cast in it (i.e. stream << static_cast <int> (value)
. That works for unsigned char
values, but then uint8_t
still gets output as a char
.
The same underlying type (i.e. unsigned/signed char
can not be used in overloads, so I can't define an overload of for example operator << (ostream &, int_fast8_t)
.
One way that comes to mind is using type traits to define the output type for each type. You would have to declare that for every type by hand. The traits could be defined as a template struct that is specialized for every data-type that has a different output-type than the data-type itself:
template< T >
struct output_trait {
typedef const T & output_type;
}
In your operator you write:
std::cout << static_cast< output_trait< T >::output_type >( variable ) << std::endl;
This will do no cast by default, but for types for which output_trait
is specialized it will do a cast:
template<>
struct output_trait< unsigned char > {
typedef unsigned int output_type;
}