我正在寻找一个标准库或Boost函数,它可以将一个数字转换成另一个原始类型,并以某种方式告诉我,该转换是否是无损的(如果不是,则抛出一个异常)。下面是一些示例:
auto x = lossless_cast<double>(1u); // ok, double can represent 1
auto x = lossless_cast<int>(1.2); // fail, int can't represent 1.2
auto x = lossless_cast<int>(1E200); // fail, int can't represent 1E200boost::numeric_cast的优势在于它将获取超出目标类型的数值范围的强制转换,但如果它们是无损的,而是在目标类型内(参见我的第二个示例)。
有一个SO question for the C language which provides some hand-rolled solutions to this problem,但我需要一个boost或标准库解决方案,基本上具有以下功能:
template <typename out, typename in>
out lossless_cast(in in_value)
{
out out_value = static_cast<out>(in_value);
if (static_cast<in>(out_value) != in_value)
throw; // some exception
return out_value;
}这个功能存在吗?
发布于 2015-05-11 04:22:58
我很确定在标准中没有任何预装的东西,也不知道有什么可以增强的,但是它是一个很大的库。任何使用强制转换的实现都必须小心未定义的行为,即每4.9 conv.fpint的超出范围值,但是当boost::numeric_cast<>表面上处理这个问题时,您可以使用:
template <typename U, typename T>
inline U is_lossless(T t)
{
U u = boost::numeric_cast<U>(t);
T t2 = boost::numeric_cast<T>(u); // throw if now out-of-range
if (t != t2)
throw whatever-you-like;
return u;
}在恢复numeric_cast<>时,对t2的需求是最不明显的:它确保u仍然在范围内,因为从int64_t x到double y的值转换成功是可能的,但是对于int64_t来说,y中的整数值比超出范围的值可以近似,这样从double转换回来具有未定义的行为。
上述行为的合法性/健壮性要求boost::numeric_cast<>正确地避免未定义的行为,而我还没有对此进行验证。
https://stackoverflow.com/questions/30158551
复制相似问题