I have the following function to convert an integer of arbitrary size to a buffer:
template<typename T>
std::string build_data_from(T val)
{
std::string result;
for (int i = 0; i < sizeof(val); i++)
{
result.insert(0, 1, char(val));
val = val >> 8;
}
return result;
}开发者_JAVA百科;
However, invoking the template function with an unsigned char renders a warning in Visual C++ 2008:
std::string x(build_data_from<unsigned char>(1));
warning C4333: '>>' : right shift by too large amount, data loss
Is there any clean way (without using a pragma warning directive) to workaround it?
The following will get rid of he warning.
change
val = val >> 8;
to
val = val >> 7 >> 1;
or
val = (val >> 7 >> 1) & 0xff;
Pretty simple: overloading build_data_from
for unsigned char
(and char
).
This can be done either by a plain overload or using std::enable_if
, I'd advise a plain overload as it'll be easier:
std::string build_data_from(char val)
{
std::string result; result += val; return result;
}
std::string build_data_from(unsigned char val)
{
return build_data_from(char(val));
}
But, you are conscious that casting an unsigned char
to a char
might produce some weird output right ? (I mean that unsigned char
might have values that are not really printable)
You can get around this with a single if
-statement:
template<typename T>
std::string build_data_from(T val)
{
std::string result;
for (size_t i = 0; i < sizeof(val); i++)
{
result.insert(0, 1, char(val));
if (sizeof (T) > 1)
val = val >> 8;
}
return result;
}
Since the conditional if (sizeof(T) > 1)
is constant for any T
the compiler will optimize it away, so no runtime overhead and no warnings. For the case that T
is a char
you even get slightly faster code because the shift gets optimized away.
Btw: You should declare your i
variable as size_t
, not int
. the result of sizeof()
is size_t
and some compilers (gcc for example) warn you if you do a comparison between signed and unsigned integers.
精彩评论