我正在寻找一个标准库或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 1E200
Run Code Online (Sandbox Code Playgroud)
boost::numeric_cast接近的是,它将拾取掉落在目标类型的数值范围之外的强制转换,但如果它们是无损但在目标类型内则不会(参见我的第二个示例).
C语言有一个问题,它为这个问题提供了一些手动解决方案,但是我正在使用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;
}
Run Code Online (Sandbox Code Playgroud)
这个功能是否存在?
我很确定标准中没有预先推出任何内容,并且不知道 boost 中有任何内容,但它是一个很大的库。任何使用强制转换的实现都必须注意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;
}
Run Code Online (Sandbox Code Playgroud)
numeric_cast<>恢复时的需求t2最不明显:它确保仍然在范围内,因为从 say到 的u值转换可能会成功,但会被近似为超出 an 范围的整数值,这样从has转换回来未定义的行为。int64_t xdouble yyint64_tdouble
上述的合法性/稳健性要求boost::numeric_cast<>正确避免未定义的行为,我尚未验证这一点。
| 归档时间: |
|
| 查看次数: |
309 次 |
| 最近记录: |