我已经为铸造字符串创建了一个模板来执行不同的数据类型,并且当数据类型是无符号字符时它会出现问题。
template<class TYPE>
bool TryParse(const std::string value, TYPE &out)
{
std::istringstream iss(value);
iss >> out;
if (iss.fail())
{
return false;
}
return true;
}
问题是istringstream
会将它看到的第一个字符视为char,而不是将其视为数字字符串。因此,如果我传递&#34; 255&#34;的值,则返回的值将为&#39; 2&#39;。
最佳解决方案是将out
变量转换为unsigned int,执行操作,然后再次转换回来吗?
答案 0 :(得分:3)
我建议有一个特别适用于unsigned char
个案例的重载,因为你需要使用中间类型。
bool TryParse(const std::string & value, unsigned char & out)
{
std::istringstream iss(value);
unsigned int i;
iss >> i;
if (iss.fail()) { return false; }
// The less-than-min check is technically redundant because both i and out
// are unsigned, but it makes me feel better having it there. It will become
// necessary for the "signed char" overload, anyway.
if (i > std::numeric_limits<unsigned char>::max() ||
i < std::numeric_limits<unsigned char>::min()) {
throw std::overflow_error();
// Or you could "return false" instead, if that makes more sense.
}
out = static_cast<unsigned char>(i);
return true;
}
您可以为signed char
使用几乎相同的功能。 (只需将每个unsigned
替换为signed
。)
我不建议在模板中使用中间类型,因为您需要使用尽可能广泛的类型,并且没有任何一种类型可以使用。例如,unsigned long long int
与signed long long int
不兼容,反之亦然 - 这些类型都不会与float
或double
兼容。拥有一个直接使用所请求类型的基本模板,对于有问题的类型(例如char
)的重载是正确的方法。
请注意,我已将value
参数更改为对const字符串的引用,因为这意味着调用者无需无理由地复制字符串。我建议你也改变你的模板功能。