我有以下函数将任意大小的整数转换为缓冲区:
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;
};
但是,使用 unsigned char 调用模板函数会在Visual C ++ 2008中显示警告:
std::string x(build_data_from<unsigned char>(1));
警告C4333:'&gt;&gt;' :右移 数量太大,数据丢失
有没有干净的方法(不使用 pragma warning 指令)来解决它?
答案 0 :(得分:3)
以下将摆脱他的警告。
更改
val = val >> 8;
到
val = val >> 7 >> 1;
或
val = (val >> 7 >> 1) & 0xff;
答案 1 :(得分:2)
非常简单:为build_data_from
(和unsigned char
)重载char
。
这可以通过普通过载或使用std::enable_if
来完成,我建议一个简单的重载,因为它会更容易:
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));
}
但是,您是否意识到将unsigned char
投射到char
可能会产生一些奇怪的输出? (我的意思是unsigned char
可能具有不可打印的值)
答案 2 :(得分:2)
您可以使用单个if
语句解决此问题:
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;
}
由于条件if (sizeof(T) > 1)
对于任何T
都是常量,编译器将对其进行优化,因此没有运行时开销和警告。对于T
是char
的情况,您甚至可以获得稍快的代码,因为转移得到了优化。
顺便说一句:您应该将i
变量声明为size_t
,而不是int
。 sizeof()
的结果是size_t
,如果你对有符号和无符号整数进行比较,一些编译器(例如gcc)会警告你。