Reputation: 1501
I have taken code from here:
http://en.wikipedia.org/wiki/Variadic_template
However it treats uint8_t and int8_t as ASCII and so I want to cast anything that is to int16_t. I tried to do this:
template<typename T, typename... Args>
void log(const char *s, T value1, Args... args)
{
while (*s) {
if (*s == '%') {
if (*(s + 1) == '%') {
++s;
}
else {
if ( std::is_same<T, uint8_t>::value || std::is_same<T, int8_t>::value )
{
int16_t x = value1;
int16_t x = static_cast<int16_t>(value1);
std::cout << x;
}
else
{
std::cout << value1;
}
log(s + 1, args...); // call even when *s == 0 to detect extra arguments
return;
}
}
std::cout << *s++;
}
throw std::logic_error("extra arguments provided to printf");
}
However I got the error:
error: invalid static_cast from type ‘std::basic_string<char, std::char_traits<char>,
std::allocator<char> >’ to type ‘int16_t’
Is there anyway not to print out ASCII?
Upvotes: 0
Views: 4914
Reputation: 15528
You seem to call your function with a std::string
, which cannot be converted to int16_t
. Instead of the static_cast
, you could use the following function template which is overloaded for strings:
template<typename T>
auto cast_to_int(T const& t) -> int16_t
{
return static_cast<int16_t>(t);
}
auto cast_to_int(std::string const& t) -> int16_t
{
std::istringstream ss(Text);
int16_t result;
ss >> result;
return result;
}
Eventually, you have to overload it for further types.
Call the above via
std::cout<< cast_to_int(value1);
instead of the whole block
if ( std::is_same<T, uint8_t>::value || std::is_same<T, int8_t>::value )
{
int16_t x = value1;
int16_t x = static_cast<int16_t>(value1);
std::cout << x;
}
else
{
std::cout << value1;
}
Upvotes: 2
Reputation: 686
Like your compiler said:
error: invalid static_cast from type ‘std::basic_string<char, std::char_traits<char>,
std::allocator<char> >’ to type ‘int16_t’
I suppose your calling your log function like this:
log("my % thing %....", /*my std::string*/ stringToto, 5,/*....*/);
And there is the problem!
When the compiler see you want to static_cast
a std::string
to a int16_t
it generate an error!
This part:
if ( std::is_same<T, uint8_t>::value || std::is_same<T, int8_t>::value )
{
int16_t x = value1;
int16_t x = static_cast<int16_t>(value1);
std::cout << x;
}
else
{
std::cout << value1;
}
Why? In fact, even if your condition (std::is_same<T, uint8_t>::value || std::is_same<T, int8_t>::value
) is false, your compiler will interpret your static_cast
Use a function that get an argument (whatever is its type) and generate an std::string, like this:
template<typename T>
std::string
my_to_string(T) { return ("what is this type?"); }
template<>
std::string
my_to_string(std::string s) { return (s); }
template<>
std::string
my_to_string(int integer) { return (std::to_string(integer)); }
and then call it in your log function like this: std::cout << my_to_string(value1);
Upvotes: 2
Reputation: 72062
If-statements don't make compile-time decisions; the compiler will always check both branches.
You need to create an overloaded write()
function, where the default version streams to cout, and which you can overload for specific types (such as char
).
Upvotes: 3